From 5a4568b2ac355f807b7ea8e7d99b812db8a01a15 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Thu, 16 Jan 2020 12:57:27 +0200 Subject: [core] Avoid repeated calculations in symbol placement --- src/mbgl/renderer/render_orchestrator.cpp | 5 +- src/mbgl/text/placement.cpp | 84 ++++++++++++++++--------------- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 5e5f2da3c3..48e7b09812 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -375,10 +375,11 @@ std::unique_ptr RenderOrchestrator::createRenderTree( } // Symbol placement. bool symbolBucketsChanged = false; + auto longitude = updateParameters->transformState.getLatLng().longitude(); if (isMapModeContinuous) { bool symbolBucketsAdded = false; for (auto it = layersNeedPlacement.crbegin(); it != layersNeedPlacement.crend(); ++it) { - auto result = crossTileSymbolIndex.addLayer(*it, updateParameters->transformState.getLatLng().longitude()); + auto result = crossTileSymbolIndex.addLayer(*it, longitude); symbolBucketsAdded = symbolBucketsAdded || (result & CrossTileSymbolIndex::AddLayerResult::BucketsAdded); symbolBucketsChanged = symbolBucketsChanged || (result != CrossTileSymbolIndex::AddLayerResult::NoChanges); } @@ -421,7 +422,7 @@ std::unique_ptr RenderOrchestrator::createRenderTree( Mutable placement = makeMutable(updateParameters); for (auto it = layersNeedPlacement.crbegin(); it != layersNeedPlacement.crend(); ++it) { const RenderLayer& layer = *it; - crossTileSymbolIndex.addLayer(layer, updateParameters->transformState.getLatLng().longitude()); + crossTileSymbolIndex.addLayer(layer, longitude); placement->placeLayer(layer, renderTreeParameters->transformParams.projMatrix); } placement->commit(); diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index edd6506c2c..dce1cb40dc 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -146,31 +146,35 @@ void Placement::placeBucket(const SymbolBucket& bucket, const auto& layout = *bucket.layout; const auto& renderTile = params.tile; const auto& state = collisionIndex.getTransformState(); - const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, state.getZoom()); + const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, placementZoom); const OverscaledTileID& overscaledID = renderTile.getOverscaledTileID(); - const float scale = std::pow(2, state.getZoom() - overscaledID.overscaledZ); + const float scale = std::pow(2, placementZoom - overscaledID.overscaledZ); const float pixelRatio = (util::tileSize * overscaledID.overscaleFactor()) / util::EXTENT; + const bool rotateTextWithMap = layout.get() == style::AlignmentType::Map; + const bool pitchTextWithMap = layout.get() == style::AlignmentType::Map; + + const bool rotateIconWithMap = layout.get() == style::AlignmentType::Map; + const bool pitchIconWithMap = layout.get() == style::AlignmentType::Map; + mat4 posMatrix; state.matrixFor(posMatrix, renderTile.id); matrix::multiply(posMatrix, params.projMatrix, posMatrix); mat4 textLabelPlaneMatrix = - getLabelPlaneMatrix(posMatrix, - layout.get() == style::AlignmentType::Map, - layout.get() == style::AlignmentType::Map, - state, - pixelsToTileUnits); - - mat4 iconLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, - layout.get() == style::AlignmentType::Map, - layout.get() == style::AlignmentType::Map, - state, - pixelsToTileUnits); + getLabelPlaneMatrix(posMatrix, pitchTextWithMap, rotateTextWithMap, state, pixelsToTileUnits); + + mat4 iconLabelPlaneMatrix; + if (rotateTextWithMap == rotateIconWithMap && pitchTextWithMap == pitchIconWithMap) { + iconLabelPlaneMatrix = textLabelPlaneMatrix; + } else { + iconLabelPlaneMatrix = + getLabelPlaneMatrix(posMatrix, pitchIconWithMap, rotateIconWithMap, state, pixelsToTileUnits); + } const auto& collisionGroup = collisionGroups.get(params.sourceId); - auto partiallyEvaluatedTextSize = bucket.textSizeBinder->evaluateForZoom(state.getZoom()); - auto partiallyEvaluatedIconSize = bucket.iconSizeBinder->evaluateForZoom(state.getZoom()); + auto partiallyEvaluatedTextSize = bucket.textSizeBinder->evaluateForZoom(placementZoom); + auto partiallyEvaluatedIconSize = bucket.iconSizeBinder->evaluateForZoom(placementZoom); optional tileBorders; optional avoidEdges; @@ -200,8 +204,7 @@ void Placement::placeBucket(const SymbolBucket& bucket, const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !(bucket.hasIconData() || bucket.hasSdfIconData()) || layout.get()); const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get()); std::vector variableTextAnchors = layout.get(); - const bool rotateWithMap = layout.get() == style::AlignmentType::Map; - const bool pitchWithMap = layout.get() == style::AlignmentType::Map; + const bool hasIconTextFit = layout.get() != style::IconTextFitType::None; const bool zOrderByViewportY = layout.get() == style::SymbolZOrderType::ViewportY; @@ -273,8 +276,8 @@ void Placement::placeBucket(const SymbolBucket& bucket, placedSymbol, scale, fontSize, - layout.get(), - pitchWithMap, + textAllowOverlap, + pitchTextWithMap, showCollisionBoxes, avoidEdges, collisionGroup.second, @@ -352,8 +355,8 @@ void Placement::placeBucket(const SymbolBucket& bucket, height, symbolInstance.variableTextOffset, textBoxScale, - rotateWithMap, - pitchWithMap, + rotateTextWithMap, + pitchTextWithMap, state.getBearing()); textBoxes.clear(); @@ -372,27 +375,28 @@ void Placement::placeBucket(const SymbolBucket& bucket, scale, fontSize, allowOverlap, - pitchWithMap, + pitchTextWithMap, showCollisionBoxes, avoidEdges, collisionGroup.second, textBoxes); if (doVariableIconPlacement) { - auto placedIconFeature = collisionIndex.placeFeature(iconCollisionFeature, - shift, - posMatrix, - iconLabelPlaneMatrix, - pixelRatio, - placedSymbol, - scale, - fontSize, - iconAllowOverlap, - pitchWithMap, - showCollisionBoxes, - avoidEdges, - collisionGroup.second, - iconBoxes); + auto placedIconFeature = + collisionIndex.placeFeature(iconCollisionFeature, + shift, + posMatrix, + iconLabelPlaneMatrix, + pixelRatio, + placedSymbol, + scale, + fontSize, + iconAllowOverlap, + pitchTextWithMap, // TODO: shall it be pitchIconWithMap? + showCollisionBoxes, + avoidEdges, + collisionGroup.second, + iconBoxes); iconBoxes.clear(); if (!placedIconFeature.first) continue; } @@ -485,8 +489,8 @@ void Placement::placeBucket(const SymbolBucket& bucket, placedSymbol, scale, fontSize, - layout.get(), - pitchWithMap, + iconAllowOverlap, + pitchTextWithMap, showCollisionBoxes, avoidEdges, collisionGroup.second, @@ -586,8 +590,8 @@ void Placement::placeBucket(const SymbolBucket& bucket, height, symbol.variableTextOffset, symbol.textBoxScale, - rotateWithMap, - pitchWithMap, + rotateTextWithMap, + pitchTextWithMap, state.getBearing()); } bool result = collisionIndex.featureIntersectsTileBorders( -- cgit v1.2.1