[core] Eliminate StyleBucket

This commit is contained in:
John Firebaugh
2015-10-20 12:21:40 -07:00
parent 8c3b3cb792
commit 540c6eca15
19 changed files with 170 additions and 231 deletions

View File

@@ -1,7 +1,6 @@
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/annotation/annotation_tile.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/layer/symbol_layer.hpp>
#include <boost/function_output_iterator.hpp>
@@ -119,12 +118,10 @@ void AnnotationManager::updateStyle(Style& style) {
layer->id = PointLayerID;
layer->type = StyleLayerType::Symbol;
layer->bucket = std::make_shared<StyleBucket>(layer->type);
layer->bucket->name = layer->id;
layer->bucket->source = SourceID;
layer->bucket->source_layer = PointLayerID;
layer->bucket->layout.set(PropertyKey::IconImage, ConstantFunction<std::string>("{sprite}"));
layer->bucket->layout.set(PropertyKey::IconAllowOverlap, ConstantFunction<bool>(true));
layer->source = SourceID;
layer->sourceLayer = PointLayerID;
layer->layout.set(PropertyKey::IconImage, ConstantFunction<std::string>("{sprite}"));
layer->layout.set(PropertyKey::IconAllowOverlap, ConstantFunction<bool>(true));
style.addLayer(std::move(layer));
}

View File

@@ -5,7 +5,6 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/layer/line_layer.hpp>
#include <mbgl/layer/fill_layer.hpp>
@@ -69,12 +68,12 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
}
layer->paints.paints = sourceLayer->paints.paints;
layer->bucket->layout = sourceLayer->bucket->layout;
layer->layout = sourceLayer->layout;
}
layer->bucket->name = layer->id;
layer->bucket->source = AnnotationManager::SourceID;
layer->bucket->source_layer = layer->id;
layer->id = layerID;
layer->source = AnnotationManager::SourceID;
layer->sourceLayer = layer->id;
style.addLayer(std::move(layer), beforeLayerID);
}
@@ -82,19 +81,15 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
std::unique_ptr<StyleLayer> ShapeAnnotationImpl::createLineLayer() {
type = ProjectedFeatureType::LineString;
std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>();
layer->id = layerID;
layer->type = StyleLayerType::Line;
layer->bucket = std::make_shared<StyleBucket>(layer->type);
layer->bucket->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round));
layer->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round));
return std::move(layer);
}
std::unique_ptr<StyleLayer> ShapeAnnotationImpl::createFillLayer() {
type = ProjectedFeatureType::Polygon;
std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>();
layer->id = layerID;
layer->type = StyleLayerType::Fill;
layer->bucket = std::make_shared<StyleBucket>(layer->type);
return std::move(layer);
}

View File

@@ -1,15 +1,14 @@
#include <mbgl/layer/line_layer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/property_parsing.hpp>
#include <mbgl/map/tile_id.hpp>
namespace mbgl {
void LineLayer::parseLayout(const JSVal& value) {
parseProperty<Function<CapType>>("line-cap", PropertyKey::LineCap, bucket->layout, value);
parseProperty<Function<JoinType>>("line-join", PropertyKey::LineJoin, bucket->layout, value);
parseProperty<Function<float>>("line-miter-limit", PropertyKey::LineMiterLimit, bucket->layout, value);
parseProperty<Function<float>>("line-round-limit", PropertyKey::LineRoundLimit, bucket->layout, value);
parseProperty<Function<CapType>>("line-cap", PropertyKey::LineCap, layout, value);
parseProperty<Function<JoinType>>("line-join", PropertyKey::LineJoin, layout, value);
parseProperty<Function<float>>("line-miter-limit", PropertyKey::LineMiterLimit, layout, value);
parseProperty<Function<float>>("line-round-limit", PropertyKey::LineRoundLimit, layout, value);
}
void LineLayer::parsePaints(const JSVal& layer) {

View File

@@ -1,42 +1,41 @@
#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/property_evaluator.hpp>
#include <mbgl/style/property_parsing.hpp>
namespace mbgl {
void SymbolLayer::parseLayout(const JSVal& value) {
parseProperty<Function<PlacementType>>("symbol-placement", PropertyKey::SymbolPlacement, bucket->layout, value);
parseProperty<Function<float>>("symbol-spacing", PropertyKey::SymbolSpacing, bucket->layout, value);
parseProperty<Function<bool>>("symbol-avoid-edges", PropertyKey::SymbolAvoidEdges, bucket->layout, value);
parseProperty<Function<bool>>("icon-allow-overlap", PropertyKey::IconAllowOverlap, bucket->layout, value);
parseProperty<Function<bool>>("icon-ignore-placement", PropertyKey::IconIgnorePlacement, bucket->layout, value);
parseProperty<Function<bool>>("icon-optional", PropertyKey::IconOptional, bucket->layout, value);
parseProperty<Function<RotationAlignmentType>>("icon-rotation-alignment", PropertyKey::IconRotationAlignment, bucket->layout, value);
parseProperty<Function<float>>("icon-size", PropertyKey::IconSize, bucket->layout, value);
parseProperty<Function<std::string>>("icon-image", PropertyKey::IconImage, bucket->layout, value);
parseProperty<Function<float>>("icon-rotate", PropertyKey::IconRotate, bucket->layout, value);
parseProperty<Function<float>>("icon-padding", PropertyKey::IconPadding, bucket->layout, value);
parseProperty<Function<bool>>("icon-keep-upright", PropertyKey::IconKeepUpright, bucket->layout, value);
parseProperty<Function<std::array<float, 2>>>("icon-offset", PropertyKey::IconOffset, bucket->layout, value);
parseProperty<Function<RotationAlignmentType>>("text-rotation-alignment", PropertyKey::TextRotationAlignment, bucket->layout, value);
parseProperty<Function<std::string>>("text-field", PropertyKey::TextField, bucket->layout, value);
parseProperty<Function<std::string>>("text-font", PropertyKey::TextFont, bucket->layout, value);
parseProperty<Function<float>>("text-size", PropertyKey::TextSize, bucket->layout, value);
parseProperty<Function<float>>("text-max-width", PropertyKey::TextMaxWidth, bucket->layout, value);
parseProperty<Function<float>>("text-line-height", PropertyKey::TextLineHeight, bucket->layout, value);
parseProperty<Function<float>>("text-letter-spacing", PropertyKey::TextLetterSpacing, bucket->layout, value);
parseProperty<Function<TextJustifyType>>("text-justify", PropertyKey::TextJustify, bucket->layout, value);
parseProperty<Function<TextAnchorType>>("text-anchor", PropertyKey::TextAnchor, bucket->layout, value);
parseProperty<Function<float>>("text-max-angle", PropertyKey::TextMaxAngle, bucket->layout, value);
parseProperty<Function<float>>("text-rotate", PropertyKey::TextRotate, bucket->layout, value);
parseProperty<Function<float>>("text-padding", PropertyKey::TextPadding, bucket->layout, value);
parseProperty<Function<bool>>("text-keep-upright", PropertyKey::TextKeepUpright, bucket->layout, value);
parseProperty<Function<TextTransformType>>("text-transform", PropertyKey::TextTransform, bucket->layout, value);
parseProperty<Function<std::array<float, 2>>>("text-offset", PropertyKey::TextOffset, bucket->layout, value);
parseProperty<Function<bool>>("text-allow-overlap", PropertyKey::TextAllowOverlap, bucket->layout, value);
parseProperty<Function<bool>>("text-ignore-placement", PropertyKey::TextIgnorePlacement, bucket->layout, value);
parseProperty<Function<bool>>("text-optional", PropertyKey::TextOptional, bucket->layout, value);
parseProperty<Function<PlacementType>>("symbol-placement", PropertyKey::SymbolPlacement, layout, value);
parseProperty<Function<float>>("symbol-spacing", PropertyKey::SymbolSpacing, layout, value);
parseProperty<Function<bool>>("symbol-avoid-edges", PropertyKey::SymbolAvoidEdges, layout, value);
parseProperty<Function<bool>>("icon-allow-overlap", PropertyKey::IconAllowOverlap, layout, value);
parseProperty<Function<bool>>("icon-ignore-placement", PropertyKey::IconIgnorePlacement, layout, value);
parseProperty<Function<bool>>("icon-optional", PropertyKey::IconOptional, layout, value);
parseProperty<Function<RotationAlignmentType>>("icon-rotation-alignment", PropertyKey::IconRotationAlignment, layout, value);
parseProperty<Function<float>>("icon-size", PropertyKey::IconSize, layout, value);
parseProperty<Function<std::string>>("icon-image", PropertyKey::IconImage, layout, value);
parseProperty<Function<float>>("icon-rotate", PropertyKey::IconRotate, layout, value);
parseProperty<Function<float>>("icon-padding", PropertyKey::IconPadding, layout, value);
parseProperty<Function<bool>>("icon-keep-upright", PropertyKey::IconKeepUpright, layout, value);
parseProperty<Function<std::array<float, 2>>>("icon-offset", PropertyKey::IconOffset, layout, value);
parseProperty<Function<RotationAlignmentType>>("text-rotation-alignment", PropertyKey::TextRotationAlignment, layout, value);
parseProperty<Function<std::string>>("text-field", PropertyKey::TextField, layout, value);
parseProperty<Function<std::string>>("text-font", PropertyKey::TextFont, layout, value);
parseProperty<Function<float>>("text-size", PropertyKey::TextSize, layout, value);
parseProperty<Function<float>>("text-max-width", PropertyKey::TextMaxWidth, layout, value);
parseProperty<Function<float>>("text-line-height", PropertyKey::TextLineHeight, layout, value);
parseProperty<Function<float>>("text-letter-spacing", PropertyKey::TextLetterSpacing, layout, value);
parseProperty<Function<TextJustifyType>>("text-justify", PropertyKey::TextJustify, layout, value);
parseProperty<Function<TextAnchorType>>("text-anchor", PropertyKey::TextAnchor, layout, value);
parseProperty<Function<float>>("text-max-angle", PropertyKey::TextMaxAngle, layout, value);
parseProperty<Function<float>>("text-rotate", PropertyKey::TextRotate, layout, value);
parseProperty<Function<float>>("text-padding", PropertyKey::TextPadding, layout, value);
parseProperty<Function<bool>>("text-keep-upright", PropertyKey::TextKeepUpright, layout, value);
parseProperty<Function<TextTransformType>>("text-transform", PropertyKey::TextTransform, layout, value);
parseProperty<Function<std::array<float, 2>>>("text-offset", PropertyKey::TextOffset, layout, value);
parseProperty<Function<bool>>("text-allow-overlap", PropertyKey::TextAllowOverlap, layout, value);
parseProperty<Function<bool>>("text-ignore-placement", PropertyKey::TextIgnorePlacement, layout, value);
parseProperty<Function<bool>>("text-optional", PropertyKey::TextOptional, layout, value);
}
void SymbolLayer::parsePaints(const JSVal& layer) {
@@ -95,13 +94,13 @@ void SymbolLayer::recalculate(const StyleCalculationParameters& parameters) {
paints.calculate(PropertyKey::TextTranslateAnchor, properties.text.translate_anchor, parameters);
// text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
auto it = bucket->layout.properties.find(PropertyKey::IconSize);
if (it != bucket->layout.properties.end()) {
auto it = layout.properties.find(PropertyKey::IconSize);
if (it != layout.properties.end()) {
const PropertyEvaluator<float> evaluator(parameters);
properties.icon.size = mapbox::util::apply_visitor(evaluator, it->second);
}
it = bucket->layout.properties.find(PropertyKey::TextSize);
if (it != bucket->layout.properties.end()) {
it = layout.properties.find(PropertyKey::TextSize);
if (it != layout.properties.end()) {
const PropertyEvaluator<float> evaluator(parameters);
properties.text.size = mapbox::util::apply_visitor(evaluator, it->second);
}

View File

@@ -40,14 +40,14 @@ TileParseResult TileWorker::parseAllLayers(std::vector<util::ptr<StyleLayer>> la
// Reset the collision tile so we have a clean slate; we're placing all features anyway.
collisionTile = std::make_unique<CollisionTile>(config);
// We're storing a list of buckets we've parsed to avoid parsing a bucket twice that is
// We're storing a set of bucket names we've parsed to avoid parsing a bucket twice that is
// referenced from more than one layer
std::set<StyleBucket*> parsed;
std::set<std::string> parsed;
for (auto i = layers.rbegin(); i != layers.rend(); i++) {
const StyleLayer& layer = **i;
if (layer.bucket && parsed.find(layer.bucket.get()) == parsed.end()) {
parsed.emplace(layer.bucket.get());
if (parsed.find(layer.bucketName()) == parsed.end()) {
parsed.emplace(layer.bucketName());
parseLayer(layer, geometryTile);
}
}
@@ -60,16 +60,16 @@ TileParseResult TileWorker::parsePendingLayers() {
// Try parsing the remaining layers that we couldn't parse in the first step due to missing
// dependencies.
for (auto it = pending.begin(); it != pending.end();) {
auto& styleBucket = it->first;
auto& layer = it->first;
auto& bucket = it->second;
assert(bucket);
if (styleBucket.type == StyleLayerType::Symbol) {
if (layer.type == StyleLayerType::Symbol) {
auto symbolBucket = dynamic_cast<SymbolBucket*>(bucket.get());
if (!symbolBucket->needsDependencies(*style.glyphStore, *style.sprite)) {
symbolBucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
*style.glyphAtlas, *style.glyphStore, *collisionTile);
insertBucket(styleBucket.name, std::move(bucket));
insertBucket(layer.bucketName(), std::move(bucket));
pending.erase(it++);
continue;
}
@@ -117,49 +117,42 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr
if (layer.type == StyleLayerType::Background)
return;
if (!layer.bucket) {
Log::Warning(Event::ParseTile, "layer '%s' does not have buckets", layer.id.c_str());
return;
}
const StyleBucket& styleBucket = *layer.bucket;
// Skip this bucket if we are to not render this
if ((styleBucket.source != sourceID) ||
(id.z < std::floor(styleBucket.min_zoom)) ||
(id.z >= std::ceil(styleBucket.max_zoom)) ||
(styleBucket.visibility == VisibilityType::None)) {
if ((layer.source != sourceID) ||
(id.z < std::floor(layer.minZoom)) ||
(id.z >= std::ceil(layer.maxZoom)) ||
(layer.visibility == VisibilityType::None)) {
return;
}
auto geometryLayer = geometryTile.getLayer(styleBucket.source_layer);
auto geometryLayer = geometryTile.getLayer(layer.sourceLayer);
if (!geometryLayer) {
// The layer specified in the bucket does not exist. Do nothing.
if (debug::tileParseWarnings) {
Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %d/%d/%d",
styleBucket.source_layer.c_str(), id.z, id.x, id.y);
layer.sourceLayer.c_str(), id.z, id.x, id.y);
}
return;
}
switch (styleBucket.type) {
switch (layer.type) {
case StyleLayerType::Fill:
createFillBucket(*geometryLayer, styleBucket);
createFillBucket(*geometryLayer, layer);
break;
case StyleLayerType::Line:
createLineBucket(*geometryLayer, styleBucket);
createLineBucket(*geometryLayer, layer);
break;
case StyleLayerType::Circle:
createCircleBucket(*geometryLayer, styleBucket);
createCircleBucket(*geometryLayer, layer);
break;
case StyleLayerType::Symbol:
createSymbolBucket(*geometryLayer, styleBucket);
createSymbolBucket(*geometryLayer, layer);
break;
case StyleLayerType::Raster:
break;
default:
Log::Warning(Event::ParseTile, "unknown bucket render type for layer '%s' (source layer '%s')",
styleBucket.name.c_str(), styleBucket.source_layer.c_str());
layer.id.c_str(), layer.sourceLayer.c_str());
}
}
@@ -179,101 +172,101 @@ void TileWorker::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& la
}
}
void TileWorker::createFillBucket(const GeometryTileLayer& layer,
const StyleBucket& styleBucket) {
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, layer, styleBucket.filter);
addBucketGeometries(bucket, tileLayer, layer.filter);
insertBucket(styleBucket.name, std::move(bucket));
insertBucket(layer.bucketName(), std::move(bucket));
}
void TileWorker::createLineBucket(const GeometryTileLayer& layer,
const StyleBucket& styleBucket) {
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, styleBucket.layout, layout.cap, z);
applyLayoutProperty(PropertyKey::LineJoin, styleBucket.layout, layout.join, z);
applyLayoutProperty(PropertyKey::LineMiterLimit, styleBucket.layout, layout.miter_limit, z);
applyLayoutProperty(PropertyKey::LineRoundLimit, styleBucket.layout, layout.round_limit, z);
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, layer, styleBucket.filter);
addBucketGeometries(bucket, tileLayer, layer.filter);
insertBucket(styleBucket.name, std::move(bucket));
insertBucket(layer.bucketName(), std::move(bucket));
}
void TileWorker::createCircleBucket(const GeometryTileLayer& layer,
const StyleBucket& styleBucket) {
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, layer, styleBucket.filter);
addBucketGeometries(bucket, tileLayer, layer.filter);
insertBucket(styleBucket.name, std::move(bucket));
insertBucket(layer.bucketName(), std::move(bucket));
}
void TileWorker::createSymbolBucket(const GeometryTileLayer& layer,
const StyleBucket& styleBucket) {
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, styleBucket.layout, layout.placement, z);
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, styleBucket.layout, layout.spacing, z);
applyLayoutProperty(PropertyKey::SymbolAvoidEdges, styleBucket.layout, layout.avoid_edges, z);
applyLayoutProperty(PropertyKey::SymbolSpacing, layer.layout, layout.spacing, z);
applyLayoutProperty(PropertyKey::SymbolAvoidEdges, layer.layout, layout.avoid_edges, z);
applyLayoutProperty(PropertyKey::IconAllowOverlap, styleBucket.layout, layout.icon.allow_overlap, z);
applyLayoutProperty(PropertyKey::IconIgnorePlacement, styleBucket.layout, layout.icon.ignore_placement, z);
applyLayoutProperty(PropertyKey::IconOptional, styleBucket.layout, layout.icon.optional, z);
applyLayoutProperty(PropertyKey::IconRotationAlignment, styleBucket.layout, layout.icon.rotation_alignment, z);
applyLayoutProperty(PropertyKey::IconImage, styleBucket.layout, layout.icon.image, z);
applyLayoutProperty(PropertyKey::IconPadding, styleBucket.layout, layout.icon.padding, z);
applyLayoutProperty(PropertyKey::IconRotate, styleBucket.layout, layout.icon.rotate, z);
applyLayoutProperty(PropertyKey::IconKeepUpright, styleBucket.layout, layout.icon.keep_upright, z);
applyLayoutProperty(PropertyKey::IconOffset, styleBucket.layout, layout.icon.offset, 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, styleBucket.layout, layout.text.rotation_alignment, z);
applyLayoutProperty(PropertyKey::TextField, styleBucket.layout, layout.text.field, z);
applyLayoutProperty(PropertyKey::TextFont, styleBucket.layout, layout.text.font, z);
applyLayoutProperty(PropertyKey::TextMaxWidth, styleBucket.layout, layout.text.max_width, z);
applyLayoutProperty(PropertyKey::TextLineHeight, styleBucket.layout, layout.text.line_height, z);
applyLayoutProperty(PropertyKey::TextLetterSpacing, styleBucket.layout, layout.text.letter_spacing, z);
applyLayoutProperty(PropertyKey::TextMaxAngle, styleBucket.layout, layout.text.max_angle, z);
applyLayoutProperty(PropertyKey::TextRotate, styleBucket.layout, layout.text.rotate, z);
applyLayoutProperty(PropertyKey::TextPadding, styleBucket.layout, layout.text.padding, z);
applyLayoutProperty(PropertyKey::TextIgnorePlacement, styleBucket.layout, layout.text.ignore_placement, z);
applyLayoutProperty(PropertyKey::TextOptional, styleBucket.layout, layout.text.optional, z);
applyLayoutProperty(PropertyKey::TextJustify, styleBucket.layout, layout.text.justify, z);
applyLayoutProperty(PropertyKey::TextAnchor, styleBucket.layout, layout.text.anchor, z);
applyLayoutProperty(PropertyKey::TextKeepUpright, styleBucket.layout, layout.text.keep_upright, z);
applyLayoutProperty(PropertyKey::TextTransform, styleBucket.layout, layout.text.transform, z);
applyLayoutProperty(PropertyKey::TextOffset, styleBucket.layout, layout.text.offset, z);
applyLayoutProperty(PropertyKey::TextAllowOverlap, styleBucket.layout, layout.text.allow_overlap, 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, styleBucket.layout, layout.icon.size, z + 1);
applyLayoutProperty(PropertyKey::IconSize, styleBucket.layout, layout.icon.max_size, 18);
applyLayoutProperty(PropertyKey::TextSize, styleBucket.layout, layout.text.size, z + 1);
applyLayoutProperty(PropertyKey::TextSize, styleBucket.layout, layout.text.max_size, 18);
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(layer, styleBucket.filter);
bucket->parseFeatures(tileLayer, layer.filter);
assert(style.glyphStore);
assert(style.sprite);
const bool needsDependencies = bucket->needsDependencies(*style.glyphStore, *style.sprite);
if (needsDependencies) {
// We cannot parse this bucket yet. Instead, we're saving it for later.
pending.emplace_back(styleBucket, std::move(bucket));
pending.emplace_back(layer, std::move(bucket));
} else {
assert(style.spriteAtlas);
assert(style.glyphAtlas);
@@ -281,7 +274,7 @@ void TileWorker::createSymbolBucket(const GeometryTileLayer& layer,
assert(collisionTile);
bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
*style.glyphAtlas, *style.glyphStore, *collisionTile);
insertBucket(styleBucket.name, std::move(bucket));
insertBucket(layer.bucketName(), std::move(bucket));
}
}

View File

@@ -23,7 +23,6 @@ class GeometryTile;
class Style;
class Bucket;
class StyleLayer;
class StyleBucket;
class GeometryTileLayer;
// We're using this class to shuttle the resulting buckets from the worker thread to the MapContext
@@ -58,10 +57,10 @@ public:
private:
void parseLayer(const StyleLayer&, const GeometryTile&);
void createFillBucket(const GeometryTileLayer&, const StyleBucket&);
void createLineBucket(const GeometryTileLayer&, const StyleBucket&);
void createCircleBucket(const GeometryTileLayer&, const StyleBucket&);
void createSymbolBucket(const GeometryTileLayer&, const StyleBucket&);
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>);
@@ -79,7 +78,7 @@ private:
// Contains buckets that we couldn't parse so far due to missing resources.
// They will be attempted on subsequent parses.
std::list<std::pair<const StyleBucket&, std::unique_ptr<Bucket>>> pending;
std::list<std::pair<const StyleLayer&, std::unique_ptr<Bucket>>> pending;
// Temporary holder
TileParseResultBuckets result;

View File

@@ -1,7 +1,6 @@
#include <mbgl/map/vector_tile_data.hpp>
#include <mbgl/map/geometry_tile.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_request.hpp>
#include <mbgl/style/style.hpp>
@@ -135,11 +134,7 @@ bool VectorTileData::parsePending(std::function<void()> callback) {
}
Bucket* VectorTileData::getBucket(const StyleLayer& layer) {
if (!layer.bucket) {
return nullptr;
}
const auto it = buckets.find(layer.bucket->name);
const auto it = buckets.find(layer.bucketName());
if (it == buckets.end()) {
return nullptr;
}

View File

@@ -8,7 +8,6 @@
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/circle_buffer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/style_properties.hpp>
namespace mbgl {

View File

@@ -6,7 +6,6 @@
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/style_properties.hpp>
#include <mbgl/util/vec.hpp>

View File

@@ -10,7 +10,6 @@
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/layer/background_layer.hpp>
@@ -294,7 +293,7 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
for (const auto& layerPtr : style.layers) {
const auto& layer = *layerPtr;
if (layer.bucket->visibility == VisibilityType::None) continue;
if (layer.visibility == VisibilityType::None) continue;
if (layer.type == StyleLayerType::Background) {
// This layer defines a background color/image.
auto& props = dynamic_cast<const BackgroundLayer&>(layer).properties;
@@ -313,13 +312,7 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
continue;
}
// This is a singular layer.
if (!layer.bucket) {
Log::Warning(Event::Render, "layer '%s' is missing bucket", layer.id.c_str());
continue;
}
Source* source = style.getSource(layer.bucket->source);
Source* source = style.getSource(layer.source);
if (!source) {
Log::Warning(Event::Render, "can't find source for layer '%s'", layer.id.c_str());
continue;
@@ -329,8 +322,8 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
// This may occur when there /is/ a bucket created for this layer, but the min/max-zoom
// is set to a fractional value, or value that is larger than the source maxzoom.
const double zoom = state.getZoom();
if (layer.bucket->min_zoom > zoom ||
layer.bucket->max_zoom <= zoom) {
if (layer.minZoom > zoom ||
layer.maxZoom <= zoom) {
continue;
}

View File

@@ -3,7 +3,6 @@
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/util/raster.hpp>
#include <mbgl/style/style_bucket.hpp>
namespace mbgl {

View File

@@ -12,8 +12,8 @@
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/text/shaping.hpp>
#include <mbgl/text/quads.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/style_properties.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <memory>
#include <map>

View File

@@ -1,7 +1,5 @@
#include <mbgl/style/property_fallback.hpp>
#include <mbgl/style/style_properties.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/style_properties.hpp>
namespace mbgl {

View File

@@ -6,7 +6,6 @@
#include <mbgl/annotation/sprite_store.hpp>
#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/style/style_bucket.hpp>
#include <mbgl/style/property_transition.hpp>
#include <mbgl/geometry/glyph_atlas.hpp>
#include <mbgl/geometry/sprite_atlas.hpp>
@@ -144,11 +143,7 @@ void Style::recalculate(float z) {
for (const auto& layer : layers) {
layer->recalculate(parameters);
if (!layer->bucket) {
continue;
}
Source* source = getSource(layer->bucket->source);
Source* source = getSource(layer->source);
if (!source) {
continue;
}

View File

@@ -1,32 +0,0 @@
#ifndef MBGL_STYLE_STYLE_BUCKET
#define MBGL_STYLE_STYLE_BUCKET
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/class_properties.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/uv.hpp>
namespace mbgl {
class StyleBucket : public util::noncopyable {
public:
typedef util::ptr<StyleBucket> Ptr;
inline StyleBucket(StyleLayerType type_) : type(type_) {}
const StyleLayerType type;
std::string name;
std::string source;
std::string source_layer;
FilterExpression filter;
ClassProperties layout;
float min_zoom = -std::numeric_limits<float>::infinity();
float max_zoom = std::numeric_limits<float>::infinity();
VisibilityType visibility = VisibilityType::Visible;
};
};
#endif

View File

@@ -27,6 +27,10 @@ std::unique_ptr<StyleLayer> StyleLayer::create(StyleLayerType type) {
}
}
const std::string& StyleLayer::bucketName() const {
return ref.empty() ? id : ref;
}
void StyleLayer::cascade(const std::vector<std::string>& classes,
const TimePoint& now,
const PropertyTransition& defaultTransition) {

View File

@@ -2,6 +2,8 @@
#define MBGL_STYLE_STYLE_LAYER
#include <mbgl/style/types.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/class_properties.hpp>
#include <mbgl/style/paint_properties_map.hpp>
#include <mbgl/renderer/render_pass.hpp>
@@ -17,7 +19,6 @@
namespace mbgl {
class StyleBucket;
class StyleCalculationParameters;
class PropertyTransition;
@@ -32,6 +33,9 @@ public:
virtual void parseLayout(const JSVal& value) = 0;
virtual void parsePaints(const JSVal& value) = 0;
// If the layer has a ref, the ref. Otherwise, the id.
const std::string& bucketName() const;
// Partially evaluate paint properties based on a set of classes.
void cascade(const std::vector<std::string>& classNames,
const TimePoint& now,
@@ -47,14 +51,16 @@ public:
bool hasRenderPass(RenderPass) const;
public:
StyleLayerType type;
std::string id;
StyleLayerType type = StyleLayerType::Unknown;
// Bucket information, telling the renderer how to generate the geometries
// for this layer (feature property filters, tessellation instructions, ...).
util::ptr<StyleBucket> bucket;
// Contains all paint classes that can be applied to this layer.
std::string ref;
std::string source;
std::string sourceLayer;
FilterExpression filter;
float minZoom = -std::numeric_limits<float>::infinity();
float maxZoom = std::numeric_limits<float>::infinity();
VisibilityType visibility = VisibilityType::Visible;
ClassProperties layout;
PaintPropertiesMap paints;
protected:

View File

@@ -187,7 +187,13 @@ void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::pt
layer = StyleLayer::create(reference->type);
layer->id = id;
layer->type = reference->type;
layer->bucket = reference->bucket;
layer->source = reference->source;
layer->sourceLayer = reference->sourceLayer;
layer->filter = reference->filter;
layer->minZoom = reference->minZoom;
layer->maxZoom = reference->maxZoom;
layer->visibility = reference->visibility;
layer->layout = reference->layout;
} else {
// Otherwise, parse the source/source-layer/filter/render keys to form the bucket.
@@ -213,18 +219,14 @@ void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::pt
layer->id = id;
layer->type = typeClass;
layer->bucket = std::make_shared<StyleBucket>(layer->type);
// We name the buckets according to the layer that defined it.
layer->bucket->name = layer->id;
if (value.HasMember("source")) {
const JSVal& value_source = value["source"];
if (value_source.IsString()) {
layer->bucket->source = { value_source.GetString(), value_source.GetStringLength() };
auto source_it = sourcesMap.find(layer->bucket->source);
layer->source = { value_source.GetString(), value_source.GetStringLength() };
auto source_it = sourcesMap.find(layer->source);
if (source_it == sourcesMap.end()) {
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", layer->bucket->source.c_str(), layer->id.c_str());
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", layer->source.c_str(), layer->id.c_str());
}
} else {
Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", layer->id.c_str());
@@ -234,20 +236,20 @@ void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::pt
if (value.HasMember("source-layer")) {
const JSVal& value_source_layer = value["source-layer"];
if (value_source_layer.IsString()) {
layer->bucket->source_layer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
layer->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
} else {
Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", layer->id.c_str());
}
}
if (value.HasMember("filter")) {
layer->bucket->filter = parseFilterExpression(value["filter"]);
layer->filter = parseFilterExpression(value["filter"]);
}
if (value.HasMember("minzoom")) {
const JSVal& min_zoom = value["minzoom"];
if (min_zoom.IsNumber()) {
layer->bucket->min_zoom = min_zoom.GetDouble();
layer->minZoom = min_zoom.GetDouble();
} else {
Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", layer->id.c_str());
}
@@ -256,14 +258,14 @@ void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::pt
if (value.HasMember("maxzoom")) {
const JSVal& max_zoom = value["maxzoom"];
if (max_zoom.IsNumber()) {
layer->bucket->max_zoom = max_zoom.GetDouble();
layer->maxZoom = max_zoom.GetDouble();
} else {
Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", layer->id.c_str());
}
}
if (value.HasMember("layout")) {
parseVisibility(*layer->bucket, value["layout"]);
parseVisibility(*layer, value["layout"]);
layer->parseLayout(value["layout"]);
}
}
@@ -283,15 +285,15 @@ void StyleParser::parseGlyphURL(const JSVal& value) {
}
}
void StyleParser::parseVisibility(StyleBucket& bucket, const JSVal& value) {
void StyleParser::parseVisibility(StyleLayer& layer, const JSVal& value) {
if (!value.HasMember("visibility")) {
return;
} else if (!value["visibility"].IsString()) {
Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string");
bucket.visibility = VisibilityType::Visible;
layer.visibility = VisibilityType::Visible;
return;
}
bucket.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
layer.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
}
}

View File

@@ -5,7 +5,6 @@
#include <mbgl/util/ptr.hpp>
#include <rapidjson/document.h>
#include <mbgl/style/style_bucket.hpp>
#include <vector>
#include <memory>
@@ -46,7 +45,7 @@ private:
void parseLayer(const std::string& id, const JSVal&, util::ptr<StyleLayer>&);
void parseSprite(const JSVal&);
void parseGlyphURL(const JSVal&);
void parseVisibility(StyleBucket&, const JSVal& value);
void parseVisibility(StyleLayer&, const JSVal& value);
std::uint8_t version;