[core] simplify dependency layout process and refactor data structures
This commit is contained in:
@@ -95,6 +95,7 @@ src/mbgl/gl/vertex_buffer.hpp
|
||||
# layout
|
||||
src/mbgl/layout/clip_lines.cpp
|
||||
src/mbgl/layout/clip_lines.hpp
|
||||
src/mbgl/layout/layout.hpp
|
||||
src/mbgl/layout/merge_lines.cpp
|
||||
src/mbgl/layout/merge_lines.hpp
|
||||
src/mbgl/layout/pattern_layout.hpp
|
||||
|
||||
36
src/mbgl/layout/layout.hpp
Normal file
36
src/mbgl/layout/layout.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer_type.hpp>
|
||||
#include <mbgl/renderer/image_atlas.hpp>
|
||||
#include <mbgl/text/glyph_atlas.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Bucket;
|
||||
class BucketParameters;
|
||||
class RenderLayer;
|
||||
class FeatureIndex;
|
||||
|
||||
class Layout {
|
||||
public:
|
||||
Layout() = default;
|
||||
virtual ~Layout() = default;
|
||||
|
||||
virtual void createBucket(const ImagePositions&,
|
||||
std::unique_ptr<FeatureIndex>&,
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>>&,
|
||||
const bool,
|
||||
const bool) = 0;
|
||||
|
||||
virtual void prepareSymbols(const GlyphMap&, const GlyphPositions&,
|
||||
const ImageMap&, const ImagePositions&) {};
|
||||
|
||||
virtual bool hasSymbolInstances() const {
|
||||
return true;
|
||||
};
|
||||
|
||||
virtual bool hasDependencies() const = 0;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/renderer/bucket_parameters.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
@@ -22,13 +23,14 @@ public:
|
||||
};
|
||||
|
||||
template <class B>
|
||||
class PatternLayout {
|
||||
class PatternLayout : public Layout {
|
||||
public:
|
||||
PatternLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& layers,
|
||||
std::unique_ptr<GeometryTileLayer> sourceLayer_,
|
||||
ImageDependencies& patternDependencies)
|
||||
: bucketLeaderID(layers.at(0)->getID()),
|
||||
: Layout(),
|
||||
bucketLeaderID(layers.at(0)->getID()),
|
||||
sourceLayer(std::move(sourceLayer_)),
|
||||
zoom(parameters.tileID.overscaledZ),
|
||||
overscaling(parameters.tileID.overscaleFactor()),
|
||||
@@ -90,12 +92,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool pattern() {
|
||||
~PatternLayout() final = default;
|
||||
|
||||
bool hasDependencies() const override {
|
||||
return hasPattern;
|
||||
}
|
||||
|
||||
std::unique_ptr<B> createBucket(const ImagePositions& patternPositions, std::unique_ptr<FeatureIndex>& featureIndex) {
|
||||
auto bucket = std::make_unique<B>(layout, layerPaintProperties, zoom, overscaling);
|
||||
void createBucket(const ImagePositions& patternPositions, std::unique_ptr<FeatureIndex>& featureIndex, std::unordered_map<std::string, std::shared_ptr<Bucket>>& buckets, const bool, const bool) override {
|
||||
auto bucket = std::make_shared<B>(layout, layerPaintProperties, zoom, overscaling);
|
||||
for (auto & patternFeature : features) {
|
||||
const auto i = patternFeature.i;
|
||||
std::unique_ptr<GeometryTileFeature> feature = std::move(patternFeature.feature);
|
||||
@@ -105,7 +109,11 @@ public:
|
||||
bucket->addFeature(*feature, geometries, patternPositions, patterns);
|
||||
featureIndex->insert(geometries, i, sourceLayerID, groupID);
|
||||
}
|
||||
return bucket;
|
||||
if (bucket->hasData()) {
|
||||
for (const auto& pair : layerPaintProperties) {
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::map<std::string, typename B::PossiblyEvaluatedPaintProperties> layerPaintProperties;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/layout/symbol_layout.hpp>
|
||||
#include <mbgl/layout/merge_lines.hpp>
|
||||
#include <mbgl/layout/clip_lines.hpp>
|
||||
@@ -40,7 +41,8 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
std::unique_ptr<GeometryTileLayer> sourceLayer_,
|
||||
ImageDependencies& imageDependencies,
|
||||
GlyphDependencies& glyphDependencies)
|
||||
: bucketLeaderID(layers.at(0)->getID()),
|
||||
: Layout(),
|
||||
bucketLeaderID(layers.at(0)->getID()),
|
||||
sourceLayer(std::move(sourceLayer_)),
|
||||
overscaling(parameters.tileID.overscaleFactor()),
|
||||
zoom(parameters.tileID.overscaledZ),
|
||||
@@ -149,11 +151,15 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
}
|
||||
}
|
||||
|
||||
bool SymbolLayout::hasDependencies() const {
|
||||
return features.size() != 0;
|
||||
}
|
||||
|
||||
bool SymbolLayout::hasSymbolInstances() const {
|
||||
return !symbolInstances.empty();
|
||||
}
|
||||
|
||||
void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions,
|
||||
void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions,
|
||||
const ImageMap& imageMap, const ImagePositions& imagePositions) {
|
||||
const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map &&
|
||||
layout.get<SymbolPlacement>() != SymbolPlacementType::Point;
|
||||
@@ -394,11 +400,11 @@ std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const
|
||||
return tileDistances;
|
||||
}
|
||||
|
||||
std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes) {
|
||||
void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIndex>&, std::unordered_map<std::string, std::shared_ptr<Bucket>>& buckets, const bool firstLoad, const bool showCollisionBoxes) {
|
||||
const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
|
||||
layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>();
|
||||
|
||||
auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, mayOverlap, bucketLeaderID, std::move(symbolInstances));
|
||||
auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, mayOverlap, bucketLeaderID, std::move(symbolInstances));
|
||||
|
||||
for (SymbolInstance &symbolInstance : bucket->symbolInstances) {
|
||||
|
||||
@@ -469,8 +475,15 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes)
|
||||
if (showCollisionBoxes) {
|
||||
addToDebugBuffers(*bucket);
|
||||
}
|
||||
if (bucket->hasData()){
|
||||
for (const auto& pair : layerPaintProperties) {
|
||||
if (!firstLoad) {
|
||||
bucket->justReloaded = true;
|
||||
}
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
}
|
||||
|
||||
return bucket;
|
||||
}
|
||||
|
||||
template <typename Buffer>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mbgl/layout/symbol_feature.hpp>
|
||||
@@ -25,20 +26,23 @@ namespace style {
|
||||
class Filter;
|
||||
} // namespace style
|
||||
|
||||
class SymbolLayout {
|
||||
class SymbolLayout : public Layout {
|
||||
public:
|
||||
SymbolLayout(const BucketParameters&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>,
|
||||
ImageDependencies&,
|
||||
GlyphDependencies&);
|
||||
|
||||
~SymbolLayout() final = default;
|
||||
|
||||
void prepare(const GlyphMap&, const GlyphPositions&,
|
||||
const ImageMap&, const ImagePositions&);
|
||||
void prepareSymbols(const GlyphMap&, const GlyphPositions&,
|
||||
const ImageMap&, const ImagePositions&) override;
|
||||
|
||||
std::unique_ptr<SymbolBucket> place(const bool showCollisionBoxes);
|
||||
void createBucket(const ImagePositions&, std::unique_ptr<FeatureIndex>&, std::unordered_map<std::string, std::shared_ptr<Bucket>>&, const bool firstLoad, const bool showCollisionBoxes) override;
|
||||
|
||||
bool hasSymbolInstances() const;
|
||||
bool hasSymbolInstances() const override;
|
||||
bool hasDependencies() const override;
|
||||
|
||||
std::map<std::string,
|
||||
std::pair<style::IconPaintProperties::PossiblyEvaluated, style::TextPaintProperties::PossiblyEvaluated>> layerPaintProperties;
|
||||
@@ -81,7 +85,7 @@ private:
|
||||
|
||||
bool sdfIcons = false;
|
||||
bool iconsNeedLinear = false;
|
||||
|
||||
|
||||
style::TextSize::UnevaluatedType textSize;
|
||||
style::IconSize::UnevaluatedType iconSize;
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParam
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<PatternLayout<FillExtrusionBucket>>
|
||||
RenderFillExtrusionLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
ImageDependencies& imageDependencies) const {
|
||||
std::unique_ptr<Layout> RenderFillExtrusionLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
GlyphDependencies&,
|
||||
ImageDependencies& imageDependencies) const {
|
||||
return std::make_unique<PatternLayout<FillExtrusionBucket>>(parameters, group, std::move(layer), imageDependencies);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ public:
|
||||
const mat4&) const override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||
|
||||
std::unique_ptr<PatternLayout<FillExtrusionBucket>>
|
||||
createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const;
|
||||
std::unique_ptr<Layout> createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>, GlyphDependencies&, ImageDependencies&) const override;
|
||||
|
||||
// Paint properties
|
||||
style::FillExtrusionPaintProperties::Unevaluated unevaluated;
|
||||
|
||||
@@ -30,10 +30,11 @@ std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters&, c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PatternLayout<FillBucket>>
|
||||
std::unique_ptr<Layout>
|
||||
RenderFillLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
GlyphDependencies&,
|
||||
ImageDependencies& imageDependencies) const {
|
||||
return std::make_unique<PatternLayout<FillBucket>>(parameters, group, std::move(layer), imageDependencies);
|
||||
}
|
||||
|
||||
@@ -33,9 +33,8 @@ public:
|
||||
const mat4&) const override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||
|
||||
std::unique_ptr<PatternLayout<FillBucket>>
|
||||
createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const;
|
||||
std::unique_ptr<Layout> createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>, GlyphDependencies&, ImageDependencies&) const override;
|
||||
|
||||
// Paint properties
|
||||
style::FillPaintProperties::Unevaluated unevaluated;
|
||||
|
||||
@@ -32,11 +32,11 @@ std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters&, c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PatternLayout<LineBucket>>
|
||||
RenderLineLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
ImageDependencies& imageDependencies) const {
|
||||
std::unique_ptr<Layout> RenderLineLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
GlyphDependencies&,
|
||||
ImageDependencies& imageDependencies) const {
|
||||
return std::make_unique<PatternLayout<LineBucket>>(parameters, group, std::move(layer), imageDependencies);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,11 @@ public:
|
||||
void updateColorRamp();
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||
std::unique_ptr<PatternLayout<LineBucket>> createLayout(const BucketParameters&,
|
||||
std::unique_ptr<Layout> createLayout(const BucketParameters&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>,
|
||||
ImageDependencies&) const;
|
||||
GlyphDependencies&,
|
||||
ImageDependencies&) const override;
|
||||
// Paint properties
|
||||
style::LinePaintProperties::Unevaluated unevaluated;
|
||||
RenderLinePaintProperties::PossiblyEvaluated evaluated;
|
||||
|
||||
@@ -36,7 +36,7 @@ std::unique_ptr<Bucket> RenderSymbolLayer::createBucket(const BucketParameters&,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParameters& parameters,
|
||||
std::unique_ptr<Layout> RenderSymbolLayer::createLayout(const BucketParameters& parameters,
|
||||
const std::vector<const RenderLayer*>& group,
|
||||
std::unique_ptr<GeometryTileLayer> layer,
|
||||
GlyphDependencies& glyphDependencies,
|
||||
|
||||
@@ -74,11 +74,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&,
|
||||
std::unique_ptr<Layout> createLayout(const BucketParameters&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>,
|
||||
GlyphDependencies&,
|
||||
ImageDependencies&) const;
|
||||
ImageDependencies&) const override;
|
||||
|
||||
// Paint properties
|
||||
style::SymbolPaintProperties::Unevaluated unevaluated;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/style/layer_type.hpp>
|
||||
@@ -79,7 +79,13 @@ public:
|
||||
const mat4&) const { return false; };
|
||||
|
||||
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;
|
||||
|
||||
virtual std::unique_ptr<Layout> createLayout(const BucketParameters&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
std::unique_ptr<GeometryTileLayer>,
|
||||
GlyphDependencies&,
|
||||
ImageDependencies&) const {
|
||||
return nullptr;
|
||||
}
|
||||
void setRenderTiles(std::vector<std::reference_wrapper<RenderTile>>);
|
||||
// Private implementation
|
||||
Immutable<style::Layer::Impl> baseImpl;
|
||||
|
||||
@@ -83,15 +83,15 @@ GeometryTileWorker::~GeometryTileWorker() = default;
|
||||
It is nevertheless possible to restart an in-progress request:
|
||||
|
||||
- [Idle] setData -> parse()
|
||||
sends getGlyphs, hasPendingSymbolDependencies() is true
|
||||
sends getGlyphs, hasPendingDependencies() is true
|
||||
enters [Coalescing], sends coalesced
|
||||
- [Coalescing] coalesced -> [Idle]
|
||||
- [Idle] setData -> new parse(), interrupts old parse()
|
||||
sends getGlyphs, hasPendingSymbolDependencies() is true
|
||||
sends getGlyphs, hasPendingDependencies() is true
|
||||
enters [Coalescing], sends coalesced
|
||||
- [Coalescing] onGlyphsAvailable -> [NeedsSymbolLayout]
|
||||
hasPendingSymbolDependencies() may or may not be true
|
||||
- [NeedsSymbolLayout] coalesced -> performSymbolLayout()
|
||||
hasPendingDependencies() may or may not be true
|
||||
- [NeedsSymbolLayout] coalesced -> finalizeLayout()
|
||||
Generates result depending on whether dependencies are met
|
||||
-> [Idle]
|
||||
|
||||
@@ -192,17 +192,17 @@ void GeometryTileWorker::symbolDependenciesChanged() {
|
||||
try {
|
||||
switch (state) {
|
||||
case Idle:
|
||||
if (!symbolLayouts.empty() || !patternLayouts.empty()) {
|
||||
if (!layouts.empty()) {
|
||||
// Layouts are created only by parsing and the parse result can only be
|
||||
// cleared by performSymbolLayout, which also clears the layouts.
|
||||
// cleared by performLayout, which also clears the layouts.
|
||||
assert(hasPendingParseResult());
|
||||
performSymbolLayout();
|
||||
finalizeLayout();
|
||||
coalesce();
|
||||
}
|
||||
break;
|
||||
|
||||
case Coalescing:
|
||||
if (!symbolLayouts.empty() || !patternLayouts.empty()) {
|
||||
if (!layouts.empty()) {
|
||||
state = NeedsSymbolLayout;
|
||||
}
|
||||
break;
|
||||
@@ -234,9 +234,9 @@ void GeometryTileWorker::coalesced() {
|
||||
|
||||
case NeedsSymbolLayout:
|
||||
// We may have entered NeedsSymbolLayout while coalescing
|
||||
// after a performSymbolLayout. In that case, we need to
|
||||
// after a performLayout. In that case, we need to
|
||||
// start over with parsing in order to do another layout.
|
||||
hasPendingParseResult() ? performSymbolLayout() : parse();
|
||||
hasPendingParseResult() ? finalizeLayout() : parse();
|
||||
coalesce();
|
||||
break;
|
||||
}
|
||||
@@ -320,23 +320,6 @@ static std::vector<std::unique_ptr<RenderLayer>> toRenderLayers(const std::vecto
|
||||
return renderLayers;
|
||||
}
|
||||
|
||||
// Helper function that takes a PatternLayout and either adds it to patternLayouts to await the
|
||||
// availability of the imageDependencies or, if the layergroup does not use a *-pattern property,
|
||||
// creates the Bucket and adds it to GeometryTileWorker::buckets.
|
||||
template <typename B>
|
||||
void GeometryTileWorker::checkPatternLayout(std::unique_ptr<PatternLayout<B>> layout) {
|
||||
if (layout->pattern()) {
|
||||
patternLayouts.push_back(std::move(layout));
|
||||
} else {
|
||||
std::shared_ptr<B> bucket = layout->createBucket({}, featureIndex);
|
||||
if (bucket->hasData()) {
|
||||
for (const auto& pair : layout->layerPaintProperties) {
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryTileWorker::parse() {
|
||||
if (!data || !layers) {
|
||||
return;
|
||||
@@ -347,8 +330,7 @@ void GeometryTileWorker::parse() {
|
||||
std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap;
|
||||
|
||||
buckets.clear();
|
||||
symbolLayouts.clear();
|
||||
patternLayouts.clear();
|
||||
layouts.clear();
|
||||
|
||||
featureIndex = std::make_unique<FeatureIndex>(*data ? (*data)->clone() : nullptr);
|
||||
BucketParameters parameters { id, mode, pixelRatio };
|
||||
@@ -382,26 +364,18 @@ void GeometryTileWorker::parse() {
|
||||
}
|
||||
|
||||
featureIndex->setBucketLayerIDs(leader.getID(), layerIDs);
|
||||
if (leader.is<RenderSymbolLayer>()) {
|
||||
auto layout = leader.as<RenderSymbolLayer>()->createLayout(
|
||||
parameters, group, std::move(geometryLayer), glyphDependencies, imageDependencies);
|
||||
symbolLayouts.push_back(std::move(layout));
|
||||
} else if (leader.is<RenderLineLayer>()) {
|
||||
// Layers that support pattern properties have an extra step at layout time to figure out what images
|
||||
// are needed to render the layer. They use the intermediate PatternLayout data structure to accomplish this,
|
||||
// and either immediately create a bucket if no pattern properties are used, or the PatternLayout is stored until
|
||||
// the images are available to add the features to the buckets.
|
||||
std::unique_ptr<PatternLayout<LineBucket>> layout = leader.as<RenderLineLayer>()->createLayout(
|
||||
parameters, group, std::move(geometryLayer), imageDependencies);
|
||||
checkPatternLayout(std::move(layout));
|
||||
} else if (leader.is<RenderFillLayer>()) {
|
||||
std::unique_ptr<PatternLayout<FillBucket>> layout = leader.as<RenderFillLayer>()->createLayout(
|
||||
parameters, group, std::move(geometryLayer), imageDependencies);
|
||||
checkPatternLayout(std::move(layout));
|
||||
} else if (leader.is<RenderFillExtrusionLayer>()) {
|
||||
std::unique_ptr<PatternLayout<FillExtrusionBucket>> layout = leader.as<RenderFillExtrusionLayer>()->createLayout(
|
||||
parameters, group, std::move(geometryLayer), imageDependencies);
|
||||
checkPatternLayout(std::move(layout));
|
||||
|
||||
// Symbol layers and layers that support pattern properties have an extra step at layout time to figure out what images/glyphs
|
||||
// are needed to render the layer. They use the intermediate Layout data structure to accomplish this,
|
||||
// and either immediately create a bucket if no images/glyphs are used, or the Layout is stored until
|
||||
// the images/glyphs are available to add the features to the buckets.
|
||||
if (leader.as<RenderSymbolLayer>() ||leader.as<RenderLineLayer>() || leader.as<RenderFillLayer>() || leader.as<RenderFillExtrusionLayer>()) {
|
||||
auto layout = leader.createLayout(parameters, group, std::move(geometryLayer), glyphDependencies, imageDependencies);
|
||||
if (layout->hasDependencies()) {
|
||||
layouts.push_back(std::move(layout));
|
||||
} else {
|
||||
layout->createBucket({}, featureIndex, buckets, firstLoad, showCollisionBoxes);
|
||||
}
|
||||
} else {
|
||||
const Filter& filter = leader.baseImpl->filter;
|
||||
const std::string& sourceLayerID = leader.baseImpl->sourceLayer;
|
||||
@@ -436,10 +410,10 @@ void GeometryTileWorker::parse() {
|
||||
" SourceID: " << sourceID.c_str() <<
|
||||
" Canonical: " << static_cast<int>(id.canonical.z) << "/" << id.canonical.x << "/" << id.canonical.y <<
|
||||
" Time");
|
||||
performSymbolLayout();
|
||||
finalizeLayout();
|
||||
}
|
||||
|
||||
bool GeometryTileWorker::hasPendingSymbolDependencies() const {
|
||||
bool GeometryTileWorker::hasPendingDependencies() const {
|
||||
for (auto& glyphDependency : pendingGlyphDependencies) {
|
||||
if (!glyphDependency.second.empty()) {
|
||||
return true;
|
||||
@@ -452,69 +426,36 @@ bool GeometryTileWorker::hasPendingParseResult() const {
|
||||
return bool(featureIndex);
|
||||
}
|
||||
|
||||
void GeometryTileWorker::performSymbolLayout() {
|
||||
if (!data || !layers || !hasPendingParseResult() || hasPendingSymbolDependencies()) {
|
||||
void GeometryTileWorker::finalizeLayout() {
|
||||
if (!data || !layers || !hasPendingParseResult() || hasPendingDependencies()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MBGL_TIMING_START(watch)
|
||||
optional<AlphaImage> glyphAtlasImage;
|
||||
ImageAtlas iconAtlas = makeImageAtlas(imageMap, patternMap);
|
||||
|
||||
if (!symbolLayouts.empty()) {
|
||||
if (!layouts.empty()) {
|
||||
GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap);
|
||||
glyphAtlasImage = std::move(glyphAtlas.image);
|
||||
|
||||
for (auto& symbolLayout : symbolLayouts) {
|
||||
for (auto& layout : layouts) {
|
||||
if (obsolete) {
|
||||
return;
|
||||
}
|
||||
|
||||
symbolLayout->prepare(glyphMap, glyphAtlas.positions,
|
||||
layout->prepareSymbols(glyphMap, glyphAtlas.positions,
|
||||
imageMap, iconAtlas.iconPositions);
|
||||
|
||||
if (!symbolLayout->hasSymbolInstances()) {
|
||||
if (!layout->hasSymbolInstances()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<SymbolBucket> bucket = symbolLayout->place(showCollisionBoxes);
|
||||
for (const auto& pair : symbolLayout->layerPaintProperties) {
|
||||
if (!firstLoad) {
|
||||
bucket->justReloaded = true;
|
||||
}
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
// layout adds the bucket to buckets
|
||||
layout->createBucket(iconAtlas.patternPositions, featureIndex, buckets, firstLoad, showCollisionBoxes);
|
||||
}
|
||||
}
|
||||
symbolLayouts.clear();
|
||||
|
||||
for (auto& value : patternLayouts) {
|
||||
if (obsolete) {
|
||||
return;
|
||||
}
|
||||
|
||||
value.match(
|
||||
[&] (const std::unique_ptr<PatternLayout<LineBucket>>& linePatternLayout) {
|
||||
std::shared_ptr<LineBucket> bucket = linePatternLayout->createBucket(iconAtlas.patternPositions, featureIndex);
|
||||
for (const auto& pair : linePatternLayout->layerPaintProperties) {
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
},
|
||||
[&] (const std::unique_ptr<PatternLayout<FillBucket>>& fillPatternLayout) {
|
||||
std::shared_ptr<FillBucket> bucket = fillPatternLayout->createBucket(iconAtlas.patternPositions, featureIndex);
|
||||
for (const auto& pair : fillPatternLayout->layerPaintProperties) {
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
},
|
||||
[&] (const std::unique_ptr<PatternLayout<FillExtrusionBucket>>& fillExtrusionLayout) {
|
||||
std::shared_ptr<FillExtrusionBucket> bucket = fillExtrusionLayout->createBucket(iconAtlas.patternPositions, featureIndex);
|
||||
for (const auto& pair : fillExtrusionLayout->layerPaintProperties) {
|
||||
buckets.emplace(pair.first, bucket);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
patternLayouts.clear();
|
||||
layouts.clear();
|
||||
|
||||
firstLoad = false;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace mbgl {
|
||||
|
||||
class GeometryTile;
|
||||
class GeometryTileData;
|
||||
class SymbolLayout;
|
||||
class Layout;
|
||||
|
||||
template <class B>
|
||||
class PatternLayout;
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
private:
|
||||
void coalesced();
|
||||
void parse();
|
||||
void performSymbolLayout();
|
||||
void finalizeLayout();
|
||||
|
||||
void coalesce();
|
||||
|
||||
@@ -60,11 +60,10 @@ private:
|
||||
void requestNewImages(const ImageDependencies&);
|
||||
|
||||
void symbolDependenciesChanged();
|
||||
bool hasPendingSymbolDependencies() const;
|
||||
bool hasPendingDependencies() const;
|
||||
bool hasPendingParseResult() const;
|
||||
|
||||
template <typename B>
|
||||
void checkPatternLayout(std::unique_ptr<PatternLayout<B>> layout);
|
||||
void checkPatternLayout(std::unique_ptr<Layout> layout);
|
||||
|
||||
ActorRef<GeometryTileWorker> self;
|
||||
ActorRef<GeometryTile> parent;
|
||||
@@ -93,13 +92,7 @@ private:
|
||||
optional<std::vector<Immutable<style::Layer::Impl>>> layers;
|
||||
optional<std::unique_ptr<const GeometryTileData>> data;
|
||||
|
||||
std::vector<std::unique_ptr<SymbolLayout>> symbolLayouts;
|
||||
|
||||
using LinePatternLayout = PatternLayout<LineBucket>;
|
||||
using FillPatternLayout = PatternLayout<FillBucket>;
|
||||
using FillExtrusionPatternLayout = PatternLayout<FillExtrusionBucket>;
|
||||
|
||||
std::vector<variant<std::unique_ptr<LinePatternLayout>, std::unique_ptr<FillPatternLayout>, std::unique_ptr<FillExtrusionPatternLayout>>> patternLayouts;
|
||||
std::vector<std::unique_ptr<Layout>> layouts;
|
||||
|
||||
GlyphDependencies pendingGlyphDependencies;
|
||||
ImageDependencies pendingImageDependencies;
|
||||
|
||||
Reference in New Issue
Block a user