Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] Convert GeometryTileWorker to "one-phase" loading #11575

Merged
merged 3 commits into from
Apr 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/mbgl/geometry/feature_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

namespace mbgl {

FeatureIndex::FeatureIndex()
: grid(util::EXTENT, util::EXTENT, util::EXTENT / 16) { // 16x16 grid -> 32px cell
FeatureIndex::FeatureIndex(std::unique_ptr<const GeometryTileData> tileData_)
: grid(util::EXTENT, util::EXTENT, util::EXTENT / 16) // 16x16 grid -> 32px cell
, tileData(std::move(tileData_)) {
}

void FeatureIndex::insert(const GeometryCollection& geometries,
Expand Down Expand Up @@ -47,12 +48,15 @@ void FeatureIndex::query(
const double tileSize,
const double scale,
const RenderedQueryOptions& queryOptions,
const GeometryTileData& geometryTileData,
const UnwrappedTileID& tileID,
const std::string& sourceID,
const std::vector<const RenderLayer*>& layers,
const CollisionIndex& collisionIndex,
const float additionalQueryRadius) const {

if (!tileData) {
return;
}

// Determine query radius
const float pixelsToTileUnits = util::EXTENT / tileSize / scale;
Expand All @@ -72,13 +76,13 @@ void FeatureIndex::query(
if (indexedFeature.sortIndex == previousSortIndex) continue;
previousSortIndex = indexedFeature.sortIndex;

addFeature(result, indexedFeature, queryGeometry, queryOptions, geometryTileData, tileID.canonical, layers, bearing, pixelsToTileUnits);
addFeature(result, indexedFeature, queryGeometry, queryOptions, tileID.canonical, layers, bearing, pixelsToTileUnits);
}

std::vector<IndexedSubfeature> symbolFeatures = collisionIndex.queryRenderedSymbols(queryGeometry, tileID, sourceID);
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
for (const auto& symbolFeature : symbolFeatures) {
addFeature(result, symbolFeature, queryGeometry, queryOptions, geometryTileData, tileID.canonical, layers, bearing, pixelsToTileUnits);
addFeature(result, symbolFeature, queryGeometry, queryOptions, tileID.canonical, layers, bearing, pixelsToTileUnits);
}
}

Expand All @@ -87,7 +91,6 @@ void FeatureIndex::addFeature(
const IndexedSubfeature& indexedFeature,
const GeometryCoordinates& queryGeometry,
const RenderedQueryOptions& options,
const GeometryTileData& geometryTileData,
const CanonicalTileID& tileID,
const std::vector<const RenderLayer*>& layers,
const float bearing,
Expand All @@ -113,7 +116,7 @@ void FeatureIndex::addFeature(
}

if (!geometryTileFeature) {
sourceLayer = geometryTileData.getLayer(indexedFeature.sourceLayerName);
sourceLayer = tileData->getLayer(indexedFeature.sourceLayerName);
assert(sourceLayer);

geometryTileFeature = sourceLayer->getFeature(indexedFeature.index);
Expand Down
7 changes: 4 additions & 3 deletions src/mbgl/geometry/feature_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ class IndexedSubfeature {

class FeatureIndex {
public:
FeatureIndex();
FeatureIndex(std::unique_ptr<const GeometryTileData> tileData_);

const GeometryTileData* getData() { return tileData.get(); }

void insert(const GeometryCollection&, std::size_t index, const std::string& sourceLayerName, const std::string& bucketName);

void query(
Expand All @@ -61,7 +63,6 @@ class FeatureIndex {
const double tileSize,
const double scale,
const RenderedQueryOptions& options,
const GeometryTileData&,
const UnwrappedTileID&,
const std::string&,
const std::vector<const RenderLayer*>&,
Expand All @@ -83,7 +84,6 @@ class FeatureIndex {
const IndexedSubfeature&,
const GeometryCoordinates& queryGeometry,
const RenderedQueryOptions& options,
const GeometryTileData&,
const CanonicalTileID&,
const std::vector<const RenderLayer*>&,
const float bearing,
Expand All @@ -93,5 +93,6 @@ class FeatureIndex {
unsigned int sortIndex = 0;

std::unordered_map<std::string, std::vector<std::string>> bucketLayerIDs;
std::unique_ptr<const GeometryTileData> tileData;
};
} // namespace mbgl
62 changes: 15 additions & 47 deletions src/mbgl/tile/geometry_tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,36 +125,16 @@ void GeometryTile::setShowCollisionBoxes(const bool showCollisionBoxes_) {
}

void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelationID) {
// Don't mark ourselves loaded or renderable until the first successful placement
// TODO: Ideally we'd render this tile without symbols as long as this tile wasn't
// replacing a tile at a different zoom that _did_ have symbols.
(void)resultCorrelationID;
nonSymbolBuckets = std::move(result.nonSymbolBuckets);
// It is possible for multiple onLayouts to be called before an onPlacement is called, in which
// case we will discard previous pending data
pendingFeatureIndex = {{ false, std::move(result.featureIndex) }};
pendingData = {{ false, std::move(result.tileData) }};
observer->onTileChanged(*this);
}

void GeometryTile::onPlacement(PlacementResult result, const uint64_t resultCorrelationID) {
loaded = true;
renderable = true;
if (resultCorrelationID == correlationID) {
pending = false;
}
symbolBuckets = std::move(result.symbolBuckets);
// When symbolBuckets arrive, mark pendingData/FeatureIndex as "ready for commit" at the
// time of the next global placement. We are counting on these symbolBuckets being
// in sync with the data/index in the last `onLayout` call, even though the correlation IDs
// may not be the same (e.g. "setShowCollisionBoxes" could bump the correlation ID while
// waiting for glyph dependencies)
if (pendingData) {
pendingData->first = true;
}
if (pendingFeatureIndex) {
pendingFeatureIndex->first = true;
}

buckets = std::move(result.buckets);

featureIndexPendingCommit = { std::move(result.featureIndex) };

if (result.glyphAtlasImage) {
glyphAtlasImage = std::move(*result.glyphAtlasImage);
}
Expand Down Expand Up @@ -196,11 +176,7 @@ void GeometryTile::upload(gl::Context& context) {
}
};

for (auto& entry : nonSymbolBuckets) {
uploadFn(*entry.second);
}

for (auto& entry : symbolBuckets) {
for (auto& entry : buckets) {
uploadFn(*entry.second);
}

Expand All @@ -216,7 +192,6 @@ void GeometryTile::upload(gl::Context& context) {
}

Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
const auto& buckets = layer.type == LayerType::Symbol ? symbolBuckets : nonSymbolBuckets;
const auto it = buckets.find(layer.id);
if (it == buckets.end()) {
return nullptr;
Expand All @@ -227,17 +202,11 @@ Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
}

void GeometryTile::commitFeatureIndex() {
// We commit our pending FeatureIndex and GeometryTileData when:
// 1) An `onPlacement` result has delivered us updated symbolBuckets since we received the pending data
// 2) A global placement has run, synchronizing the global CollisionIndex with the latest
// symbolBuckets (and thus with the latest FeatureIndex/GeometryTileData)
if (pendingFeatureIndex && pendingFeatureIndex->first) {
featureIndex = std::move(pendingFeatureIndex->second);
pendingFeatureIndex = nullopt;
}
if (pendingData && pendingData->first) {
data = std::move(pendingData->second);
pendingData = nullopt;
// We commit our pending FeatureIndex when a global placement has run,
// synchronizing the global CollisionIndex with the latest buckets/FeatureIndex
if (featureIndexPendingCommit) {
featureIndex = std::move(*featureIndexPendingCommit);
featureIndexPendingCommit = nullopt;
}
}

Expand All @@ -249,7 +218,7 @@ void GeometryTile::queryRenderedFeatures(
const RenderedQueryOptions& options,
const CollisionIndex& collisionIndex) {

if (!featureIndex || !data) return;
if (!getData()) return;

// Determine the additional radius needed factoring in property functions
float additionalRadius = 0;
Expand All @@ -266,7 +235,6 @@ void GeometryTile::queryRenderedFeatures(
util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ),
options,
*data,
id.toUnwrapped(),
sourceID,
layers,
Expand All @@ -278,8 +246,8 @@ void GeometryTile::querySourceFeatures(
std::vector<Feature>& result,
const SourceQueryOptions& options) {

// Data not yet available
if (!data) {
// Data not yet available, or tile is empty
if (!getData()) {
return;
}

Expand All @@ -292,7 +260,7 @@ void GeometryTile::querySourceFeatures(
for (auto sourceLayer : *options.sourceLayers) {
// Go throught all sourceLayers, if any
// to gather all the features
auto layer = data->getLayer(sourceLayer);
auto layer = getData()->getLayer(sourceLayer);

if (layer) {
auto featureCount = layer->featureCount();
Expand Down
39 changes: 12 additions & 27 deletions src/mbgl/tile/geometry_tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,21 @@ class GeometryTile : public Tile, public GlyphRequestor, ImageRequestor {

class LayoutResult {
public:
std::unordered_map<std::string, std::shared_ptr<Bucket>> nonSymbolBuckets;
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
std::unique_ptr<FeatureIndex> featureIndex;
std::unique_ptr<GeometryTileData> tileData;

LayoutResult(std::unordered_map<std::string, std::shared_ptr<Bucket>> nonSymbolBuckets_,
std::unique_ptr<FeatureIndex> featureIndex_,
std::unique_ptr<GeometryTileData> tileData_)
: nonSymbolBuckets(std::move(nonSymbolBuckets_)),
featureIndex(std::move(featureIndex_)),
tileData(std::move(tileData_)) {}
};
void onLayout(LayoutResult, uint64_t correlationID);

class PlacementResult {
public:
std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
optional<AlphaImage> glyphAtlasImage;
optional<PremultipliedImage> iconAtlasImage;

PlacementResult(std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets_,
optional<AlphaImage> glyphAtlasImage_,
optional<PremultipliedImage> iconAtlasImage_)
: symbolBuckets(std::move(symbolBuckets_)),
LayoutResult(std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets_,
std::unique_ptr<FeatureIndex> featureIndex_,
optional<AlphaImage> glyphAtlasImage_,
optional<PremultipliedImage> iconAtlasImage_)
: buckets(std::move(buckets_)),
featureIndex(std::move(featureIndex_)),
glyphAtlasImage(std::move(glyphAtlasImage_)),
iconAtlasImage(std::move(iconAtlasImage_)) {}
};
void onPlacement(PlacementResult, uint64_t correlationID);
void onLayout(LayoutResult, uint64_t correlationID);

void onError(std::exception_ptr, uint64_t correlationID);

Expand All @@ -104,7 +92,7 @@ class GeometryTile : public Tile, public GlyphRequestor, ImageRequestor {

protected:
const GeometryTileData* getData() {
return data.get();
return featureIndex ? featureIndex->getData() : nullptr;
}

private:
Expand All @@ -123,17 +111,14 @@ class GeometryTile : public Tile, public GlyphRequestor, ImageRequestor {

uint64_t correlationID = 0;

std::unordered_map<std::string, std::shared_ptr<Bucket>> nonSymbolBuckets;
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;

optional<std::unique_ptr<FeatureIndex>> featureIndexPendingCommit;
std::unique_ptr<FeatureIndex> featureIndex;
optional<std::pair<bool,std::unique_ptr<FeatureIndex>>> pendingFeatureIndex;
std::unique_ptr<const GeometryTileData> data;
optional<std::pair<bool, std::unique_ptr<const GeometryTileData>>> pendingData;

optional<AlphaImage> glyphAtlasImage;
optional<PremultipliedImage> iconAtlasImage;

std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;

const MapMode mode;

bool showCollisionBoxes;
Expand Down
Loading