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

[core] Few performance fixes for RendererImpl #14930

Merged
merged 3 commits into from
Jul 9, 2019
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
2 changes: 2 additions & 0 deletions platform/android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to

## master

* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))

## 8.2.0-alpha.2 - July 3, 2019

### Bugs
Expand Down
4 changes: 4 additions & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started.

## master

* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))

## 5.2.0

### Offline maps
Expand Down
1 change: 1 addition & 0 deletions platform/macos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Added an `MGLMapView.prefetchesTiles` property to configure lower-resolution tile prefetching behavior. ([#14816](https://github.com/mapbox/mapbox-gl-native/pull/14816))
* Fixed queryRenderedFeatues bug caused by incorrect sort feature index calculation. ([#14884](https://github.com/mapbox/mapbox-gl-native/pull/14884))
* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))

### Styles and rendering

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/annotation/render_annotation_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void RenderAnnotationSource::update(Immutable<style::Source::Impl> baseImpl_,
std::unordered_map<std::string, std::vector<Feature>>
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/annotation/render_annotation_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class RenderAnnotationSource final : public RenderTileSource {
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const final;

Expand Down
21 changes: 7 additions & 14 deletions src/mbgl/geometry/feature_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void FeatureIndex::query(
const double scale,
const RenderedQueryOptions& queryOptions,
const UnwrappedTileID& tileID,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const float additionalQueryPadding) const {

if (!tileData) {
Expand Down Expand Up @@ -81,7 +81,7 @@ void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>
FeatureIndex::lookupSymbolFeatures(const std::vector<IndexedSubfeature>& symbolFeatures,
const RenderedQueryOptions& queryOptions,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const OverscaledTileID& tileID,
const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const {
std::unordered_map<std::string, std::vector<Feature>> result;
Expand Down Expand Up @@ -123,31 +123,24 @@ void FeatureIndex::addFeature(
const IndexedSubfeature& indexedFeature,
const RenderedQueryOptions& options,
const CanonicalTileID& tileID,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
const float pixelsToTileUnits,
const mat4& posMatrix) const {

auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* {
for (const auto& layer : layers) {
if (layer->getID() == layerID) {
return layer;
}
}
return nullptr;
};

// Lazily calculated.
std::unique_ptr<GeometryTileLayer> sourceLayer;
std::unique_ptr<GeometryTileFeature> geometryTileFeature;

for (const std::string& layerID : bucketLayerIDs.at(indexedFeature.bucketLeaderID)) {
const RenderLayer* renderLayer = getRenderLayer(layerID);
if (!renderLayer) {
const auto it = layers.find(layerID);
if (it == layers.end()) {
continue;
}

const RenderLayer* renderLayer = it->second;

if (!geometryTileFeature) {
sourceLayer = tileData->getLayer(indexedFeature.sourceLayerName);
assert(sourceLayer);
Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/geometry/feature_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class FeatureIndex {
const double scale,
const RenderedQueryOptions& options,
const UnwrappedTileID&,
const std::vector<const RenderLayer*>&,
const std::unordered_map<std::string, const RenderLayer*>&,
const float additionalQueryPadding) const;

static optional<GeometryCoordinates> translateQueryGeometry(
Expand All @@ -82,7 +82,7 @@ class FeatureIndex {
std::unordered_map<std::string, std::vector<Feature>> lookupSymbolFeatures(
const std::vector<IndexedSubfeature>& symbolFeatures,
const RenderedQueryOptions& options,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const OverscaledTileID& tileID,
const std::shared_ptr<std::vector<size_t>>& featureSortOrder) const;

Expand All @@ -92,7 +92,7 @@ class FeatureIndex {
const IndexedSubfeature&,
const RenderedQueryOptions& options,
const CanonicalTileID&,
const std::vector<const RenderLayer*>&,
const std::unordered_map<std::string, const RenderLayer*>&,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
const float pixelsToTileUnits,
Expand Down
53 changes: 36 additions & 17 deletions src/mbgl/renderer/render_orchestrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,17 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
std::vector<std::reference_wrapper<RenderLayer>> layersNeedPlacement;
auto renderItemsEmplaceHint = layerRenderItems.begin();

// Reserve size for filteredLayersForSource if there are sources.
if (!sourceImpls->empty()) {
filteredLayersForSource.reserve(layerImpls->size());
if (filteredLayersForSource.capacity() > layerImpls->size()) {
filteredLayersForSource.shrink_to_fit();
}
}

// Update all sources and initialize renderItems.
for (const auto& sourceImpl : *sourceImpls) {
RenderSource* source = renderSources.at(sourceImpl->id).get();
std::vector<Immutable<LayerProperties>> filteredLayersForSource;
filteredLayersForSource.reserve(layerImpls->size());
bool sourceNeedsRendering = false;
bool sourceNeedsRelayout = false;

Expand Down Expand Up @@ -321,6 +327,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
sourceNeedsRendering,
sourceNeedsRelayout,
tileParameters);
filteredLayersForSource.clear();
}

renderTreeParameters->loaded = updateParameters.styleLoaded && isLoaded();
Expand Down Expand Up @@ -409,16 +416,16 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
}

std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const {
std::vector<const RenderLayer*> layers;
std::unordered_map<std::string, const RenderLayer*> layers;
if (options.layerIDs) {
for (const auto& layerID : *options.layerIDs) {
if (const RenderLayer* layer = getRenderLayer(layerID)) {
layers.emplace_back(layer);
layers.emplace(layer->getID(), layer);
}
}
} else {
for (const auto& entry : renderLayers) {
layers.emplace_back(entry.second.get());
layers.emplace(entry.second->getID(), entry.second.get());
}
}

Expand All @@ -427,9 +434,22 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS

void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, std::vector<Feature>>& resultsByLayer,
const ScreenLineString& geometry,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {

const auto hasCrossTileIndex = [] (const auto& pair) {
return pair.second->baseImpl->getTypeInfo()->crossTileIndex == style::LayerTypeInfo::CrossTileIndex::Required;
};

std::unordered_map<std::string, const RenderLayer*> crossTileSymbolIndexLayers;
std::copy_if(layers.begin(),
layers.end(),
std::inserter(crossTileSymbolIndexLayers, crossTileSymbolIndexLayers.begin()),
hasCrossTileIndex);

if (crossTileSymbolIndexLayers.empty()) {
return;
}

auto renderedSymbols = placement->getCollisionIndex().queryRenderedSymbols(geometry);
std::vector<std::reference_wrapper<const RetainedQueryData>> bucketQueryData;
for (auto entry : renderedSymbols) {
Expand All @@ -447,7 +467,7 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
auto& queryData = wrappedQueryData.get();
auto bucketSymbols = queryData.featureIndex->lookupSymbolFeatures(renderedSymbols[queryData.bucketInstanceId],
options,
layers,
crossTileSymbolIndexLayers,
queryData.tileID,
queryData.featureSortOrder);

Expand All @@ -458,10 +478,10 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
}
}

std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::vector<const RenderLayer*>& layers) const {
std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::unordered_map<std::string, const RenderLayer*>& layers) const {
std::unordered_set<std::string> sourceIDs;
for (const RenderLayer* layer : layers) {
sourceIDs.emplace(layer->baseImpl->source);
for (const auto& pair : layers) {
sourceIDs.emplace(pair.second->baseImpl->source);
}

mat4 projMatrix;
Expand All @@ -484,13 +504,12 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
}

// Combine all results based on the style layer renderItems.
for (const auto& layerImpl : *layerImpls) {
const RenderLayer* layer = getRenderLayer(layerImpl->id);
if (!layer->needsRendering() || !layer->supportsZoom(zoomHistory.lastZoom)) {
for (const auto& pair : layers) {
if (!pair.second->needsRendering() || !pair.second->supportsZoom(zoomHistory.lastZoom)) {
continue;
}

auto it = resultsByLayer.find(layer->baseImpl->id);
auto it = resultsByLayer.find(pair.second->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
}
Expand All @@ -501,13 +520,13 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS

std::vector<Feature> RenderOrchestrator::queryShapeAnnotations(const ScreenLineString& geometry) const {
assert(LayerManager::annotationsEnabled);
std::vector<const RenderLayer*> shapeAnnotationLayers;
std::unordered_map<std::string, const RenderLayer*> shapeAnnotationLayers;
RenderedQueryOptions options;
for (const auto& layerImpl : *layerImpls) {
if (std::mismatch(layerImpl->id.begin(), layerImpl->id.end(),
AnnotationManager::ShapeLayerID.begin(), AnnotationManager::ShapeLayerID.end()).second == AnnotationManager::ShapeLayerID.end()) {
if (const RenderLayer* layer = getRenderLayer(layerImpl->id)) {
shapeAnnotationLayers.emplace_back(layer);
shapeAnnotationLayers.emplace(layer->getID(), layer);
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/mbgl/renderer/render_orchestrator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class PatternAtlas;
class CrossTileSymbolIndex;
class RenderTree;

namespace style {
class LayerProperties;
} // namespace style

class RenderOrchestrator final : public GlyphManagerObserver,
public ImageManagerObserver,
public RenderSourceObserver {
Expand Down Expand Up @@ -74,10 +78,10 @@ class RenderOrchestrator final : public GlyphManagerObserver,

void queryRenderedSymbols(std::unordered_map<std::string, std::vector<Feature>>& resultsByLayer,
const ScreenLineString& geometry,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options) const;

std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions&, const std::vector<const RenderLayer*>&) const;
std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions&, const std::unordered_map<std::string, const RenderLayer*>&) const;

// GlyphManagerObserver implementation.
void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
Expand Down Expand Up @@ -113,6 +117,10 @@ class RenderOrchestrator final : public GlyphManagerObserver,

const bool backgroundLayerAsColor;
bool contextLost = false;

// Vector with reserved capacity of layerImpls->size() to avoid reallocation
// on each frame.
std::vector<Immutable<style::LayerProperties>> filteredLayersForSource;
};

} // namespace mbgl
2 changes: 1 addition & 1 deletion src/mbgl/renderer/render_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class RenderSource : protected TileObserver {
virtual std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const = 0;

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_image_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
const std::vector<const RenderLayer*>&,
const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>> {};
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_image_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class RenderImageSource final : public RenderSource {
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const final;

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_raster_dem_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void RenderRasterDEMSource::onTileChanged(Tile& tile){
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
const std::vector<const RenderLayer*>&,
const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>>{};
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_raster_dem_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RenderRasterDEMSource final : public RenderTileSource {
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const override;

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_raster_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void RenderRasterSource::prepare(const SourcePrepareParameters& parameters) {
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
const std::vector<const RenderLayer*>&,
const std::unordered_map<std::string, const RenderLayer*>&,
const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>>{};
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_raster_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RenderRasterSource final : public RenderTileSource {
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const override;

Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/sources/render_tile_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const Tile* RenderTileSource::getRenderedTile(const UnwrappedTileID& tileID) con
std::unordered_map<std::string, std::vector<Feature>>
RenderTileSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const std::vector<const RenderLayer*>& layers,
const std::unordered_map<std::string, const RenderLayer*>& layers,
const RenderedQueryOptions& options,
const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
Expand Down
Loading