summaryrefslogtreecommitdiff
path: root/src/mbgl/tile/geometry_tile_worker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/tile/geometry_tile_worker.cpp')
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp99
1 files changed, 87 insertions, 12 deletions
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index 31f4b89801..973f9af737 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -2,10 +2,14 @@
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/layout/symbol_layout.hpp>
+#include <mbgl/layout/pattern_layout.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/group_by_layout.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
+#include <mbgl/renderer/layers/render_fill_layer.hpp>
+#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
+#include <mbgl/renderer/layers/render_line_layer.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
#include <mbgl/util/logging.hpp>
@@ -195,11 +199,15 @@ void GeometryTileWorker::symbolDependenciesChanged() {
assert(hasPendingParseResult());
performSymbolLayout();
coalesce();
+ } else if (patternNeedsLayout) {
+ performSymbolLayout();
+ coalesce();
}
+
break;
case Coalescing:
- if (symbolLayoutsNeedPreparation) {
+ if (symbolLayoutsNeedPreparation || patternNeedsLayout) {
state = NeedsSymbolLayout;
}
break;
@@ -267,11 +275,12 @@ void GeometryTileWorker::onGlyphsAvailable(GlyphMap newGlyphMap) {
symbolDependenciesChanged();
}
-void GeometryTileWorker::onImagesAvailable(ImageMap newImageMap, uint64_t imageCorrelationID_) {
+void GeometryTileWorker::onImagesAvailable(ImageMap newIconMap, ImageMap newPatternMap, uint64_t imageCorrelationID_) {
if (imageCorrelationID != imageCorrelationID_) {
return; // Ignore outdated image request replies.
}
- imageMap = std::move(newImageMap);
+ imageMap = std::move(newIconMap);
+ patternMap = std::move(newPatternMap);
pendingImageDependencies.clear();
symbolDependenciesChanged();
}
@@ -292,6 +301,7 @@ void GeometryTileWorker::requestNewGlyphs(const GlyphDependencies& glyphDependen
void GeometryTileWorker::requestNewImages(const ImageDependencies& imageDependencies) {
pendingImageDependencies = imageDependencies;
+
if (!pendingImageDependencies.empty()) {
parent.invoke(&GeometryTile::getImages, std::make_pair(pendingImageDependencies, ++imageCorrelationID));
}
@@ -315,6 +325,24 @@ 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));
+ patternNeedsLayout = true;
+ } 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;
@@ -329,6 +357,7 @@ void GeometryTileWorker::parse() {
}
std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap;
+
buckets.clear();
featureIndex = std::make_unique<FeatureIndex>(*data ? (*data)->clone() : nullptr);
BucketParameters parameters { id, mode, pixelRatio };
@@ -362,12 +391,27 @@ 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);
symbolLayoutMap.emplace(leader.getID(), std::move(layout));
symbolLayoutsNeedPreparation = true;
+ } 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));
} else {
const Filter& filter = leader.baseImpl->filter;
const std::string& sourceLayerID = leader.baseImpl->sourceLayer;
@@ -380,17 +424,17 @@ void GeometryTileWorker::parse() {
continue;
GeometryCollection geometries = feature->getGeometries();
- bucket->addFeature(*feature, geometries);
+ bucket->addFeature(*feature, geometries, {}, PatternLayerMap ());
featureIndex->insert(geometries, i, sourceLayerID, leader.getID());
}
if (!bucket->hasData()) {
continue;
}
-
for (const auto& layer : group) {
buckets.emplace(layer->getID(), bucket);
}
+
}
}
@@ -433,14 +477,13 @@ void GeometryTileWorker::performSymbolLayout() {
MBGL_TIMING_START(watch)
optional<AlphaImage> glyphAtlasImage;
- optional<PremultipliedImage> iconAtlasImage;
+ ImageAtlas iconAtlas;
if (symbolLayoutsNeedPreparation) {
GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap);
- ImageAtlas imageAtlas = makeImageAtlas(imageMap);
+ iconAtlas = makeImageAtlas(imageMap, patternMap);
glyphAtlasImage = std::move(glyphAtlas.image);
- iconAtlasImage = std::move(imageAtlas.image);
for (auto& symbolLayout : symbolLayouts) {
if (obsolete) {
@@ -448,12 +491,45 @@ void GeometryTileWorker::performSymbolLayout() {
}
symbolLayout->prepare(glyphMap, glyphAtlas.positions,
- imageMap, imageAtlas.positions);
+ imageMap, iconAtlas.iconPositions);
}
symbolLayoutsNeedPreparation = false;
}
+ if (!iconAtlas.image.valid()) {
+ iconAtlas = makeImageAtlas(imageMap, patternMap);
+ }
+
+ 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);
+ }
+ }
+ );
+ }
+ patternNeedsLayout = false;
+ patternLayouts.clear();
+
for (auto& symbolLayout : symbolLayouts) {
if (obsolete) {
return;
@@ -483,8 +559,7 @@ void GeometryTileWorker::performSymbolLayout() {
std::move(buckets),
std::move(featureIndex),
std::move(glyphAtlasImage),
- std::move(iconAtlasImage)
+ std::move(iconAtlas)
}, correlationID);
}
-
} // namespace mbgl