[core] retain GeometryTileLayer in SymbolLayout

We're storing GeometryTileFeature objects in SymbolLayout, but they may reference data in GeometryTileLayer, which could go away if we don't retain it.
This commit is contained in:
Konstantin Käfer
2017-06-20 15:19:12 -07:00
parent 7b90af5d35
commit 244484ca6c
5 changed files with 21 additions and 14 deletions

View File

@@ -40,10 +40,10 @@ static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout)
SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const std::vector<const RenderLayer*>& layers,
const GeometryTileLayer& sourceLayer,
std::unique_ptr<GeometryTileLayer> sourceLayer_,
ImageDependencies& imageDependencies,
GlyphDependencies& glyphDependencies)
: sourceLayerName(sourceLayer.getName()),
: sourceLayer(std::move(sourceLayer_)),
bucketName(layers.at(0)->getID()),
overscaling(parameters.tileID.overscaleFactor()),
zoom(parameters.tileID.overscaledZ),
@@ -95,9 +95,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
}
// Determine glyph dependencies
const size_t featureCount = sourceLayer.featureCount();
const size_t featureCount = sourceLayer->featureCount();
for (size_t i = 0; i < featureCount; ++i) {
auto feature = sourceLayer.getFeature(i);
auto feature = sourceLayer->getFeature(i);
if (!leader.filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }))
continue;
@@ -328,8 +328,9 @@ void SymbolLayout::addFeature(const std::size_t index,
? SymbolPlacementType::Point
: layout.get<SymbolPlacement>();
const float textRepeatDistance = symbolSpacing / 2;
IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, bucketName, symbolInstances.size()};
IndexedSubfeature indexedFeature = { feature.index, sourceLayer->getName(), bucketName,
symbolInstances.size() };
auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
// https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
// +-------------------+ Symbols with anchors located on tile edges

View File

@@ -29,7 +29,7 @@ class SymbolLayout {
public:
SymbolLayout(const BucketParameters&,
const std::vector<const RenderLayer*>&,
const GeometryTileLayer&,
std::unique_ptr<GeometryTileLayer>,
ImageDependencies&,
GlyphDependencies&);
@@ -74,7 +74,9 @@ private:
const float placementAngle,
WritingModeType writingModes);
const std::string sourceLayerName;
// Stores the layer so that we can hold on to GeometryTileFeature instances in SymbolFeature,
// which may reference data from this object.
const std::unique_ptr<GeometryTileLayer> sourceLayer;
const std::string bucketName;
const float overscaling;
const float zoom;

View File

@@ -23,12 +23,12 @@ std::unique_ptr<Bucket> RenderSymbolLayer::createBucket(const BucketParameters&,
std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParameters& parameters,
const std::vector<const RenderLayer*>& group,
const GeometryTileLayer& layer,
std::unique_ptr<GeometryTileLayer> layer,
GlyphDependencies& glyphDependencies,
ImageDependencies& imageDependencies) const {
return std::make_unique<SymbolLayout>(parameters,
group,
layer,
std::move(layer),
imageDependencies,
glyphDependencies);
}

View File

@@ -71,8 +71,11 @@ public:
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&, ImageDependencies&) const;
std::unique_ptr<SymbolLayout> createLayout(const BucketParameters&,
const std::vector<const RenderLayer*>&,
std::unique_ptr<GeometryTileLayer>,
GlyphDependencies&,
ImageDependencies&) const;
// Paint properties
style::SymbolPaintProperties::Unevaluated unevaluated;

View File

@@ -309,8 +309,9 @@ void GeometryTileWorker::redoLayout() {
featureIndex->setBucketLayerIDs(leader.getID(), layerIDs);
if (leader.is<RenderSymbolLayer>()) {
symbolLayoutMap.emplace(leader.getID(),
leader.as<RenderSymbolLayer>()->createLayout(parameters, group, *geometryLayer, glyphDependencies, imageDependencies));
auto layout = leader.as<RenderSymbolLayer>()->createLayout(
parameters, group, std::move(geometryLayer), glyphDependencies, imageDependencies);
symbolLayoutMap.emplace(leader.getID(), std::move(layout));
} else {
const Filter& filter = leader.baseImpl->filter;
const std::string& sourceLayerID = leader.baseImpl->sourceLayer;