diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-05-25 16:17:45 +0300 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-05-28 16:16:42 +0300 |
commit | 054645042a52de4d0b6d22d1ec033bc9197c9297 (patch) | |
tree | 0d3b950df885b7734483e0aa26c5139a60ba88c5 /src/mbgl/text | |
parent | a03f7b166b2fe68f63ca75337bd0ac0000cee135 (diff) | |
download | qtlocation-mapboxgl-054645042a52de4d0b6d22d1ec033bc9197c9297.tar.gz |
[core] Encapsulate symbol bucket placement code in Placement::placeLayerBucket()
Diffstat (limited to 'src/mbgl/text')
-rw-r--r-- | src/mbgl/text/placement.cpp | 134 | ||||
-rw-r--r-- | src/mbgl/text/placement.hpp | 10 |
2 files changed, 66 insertions, 78 deletions
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index dfe663a8a2..49bf3844c8 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -72,52 +72,15 @@ Placement::Placement(const TransformState& state_, MapMode mapMode_, style::Tran } void Placement::placeLayer(const RenderLayer& layer, const mat4& projMatrix, bool showCollisionBoxes) { - std::set<uint32_t> seenCrossTileIDs; - for (const auto& item : layer.getPlacementData()) { - RenderTile& renderTile = item.tile; Bucket& bucket = item.bucket; - - const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, state.getZoom()); - const OverscaledTileID& overscaledID = renderTile.getOverscaledTileID(); - const float scale = std::pow(2, state.getZoom() - overscaledID.overscaledZ); - const float textPixelRatio = (util::tileSize * overscaledID.overscaleFactor()) / util::EXTENT; - - mat4 posMatrix; - state.matrixFor(posMatrix, renderTile.id); - matrix::multiply(posMatrix, projMatrix, posMatrix); - - mat4 textLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, - item.pitchWithMap, - item.rotateWithMap, - state, - pixelsToTileUnits); - - mat4 iconLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, - item.pitchWithMap, - item.rotateWithMap, - state, - pixelsToTileUnits); - - const auto& collisionGroup = collisionGroups.get(layer.baseImpl->source); BucketPlacementParameters params{ - posMatrix, - textLabelPlaneMatrix, - iconLabelPlaneMatrix, - scale, - textPixelRatio, - showCollisionBoxes, - renderTile.holdForFade(), - collisionGroup}; - auto bucketInstanceId = bucket.place(*this, params, seenCrossTileIDs); - assert(bucketInstanceId != 0u); - - // As long as this placement lives, we have to hold onto this bucket's - // matching FeatureIndex/data for querying purposes - retainedQueryData.emplace(std::piecewise_construct, - std::forward_as_tuple(bucketInstanceId), - std::forward_as_tuple(bucketInstanceId, renderTile.getFeatureIndex(), overscaledID)); + item.tile, + projMatrix, + layer.baseImpl->source, + showCollisionBoxes}; + bucket.place(*this, params, seenCrossTileIDs); } } @@ -138,19 +101,42 @@ void Placement::placeLayerBucket( SymbolBucket& bucket, const BucketPlacementParameters& params, std::set<uint32_t>& seenCrossTileIDs) { - + const auto& layout = bucket.layout; + const auto& renderTile = params.tile; + const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, state.getZoom()); + const OverscaledTileID& overscaledID = renderTile.getOverscaledTileID(); + const float scale = std::pow(2, state.getZoom() - overscaledID.overscaledZ); + const float pixelRatio = (util::tileSize * overscaledID.overscaleFactor()) / util::EXTENT; + + mat4 posMatrix; + state.matrixFor(posMatrix, renderTile.id); + matrix::multiply(posMatrix, params.projMatrix, posMatrix); + + mat4 textLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, + layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map, + layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map, + state, + pixelsToTileUnits); + + mat4 iconLabelPlaneMatrix = getLabelPlaneMatrix(posMatrix, + layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map, + layout.get<style::IconRotationAlignment>() == style::AlignmentType::Map, + state, + pixelsToTileUnits); + + const auto& collisionGroup = collisionGroups.get(params.sourceId); auto partiallyEvaluatedTextSize = bucket.textSizeBinder->evaluateForZoom(state.getZoom()); auto partiallyEvaluatedIconSize = bucket.iconSizeBinder->evaluateForZoom(state.getZoom()); optional<CollisionTileBoundaries> avoidEdges; if (mapMode == MapMode::Tile && - (bucket.layout.get<style::SymbolAvoidEdges>() || - bucket.layout.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line)) { - avoidEdges = collisionIndex.projectTileBoundaries(params.posMatrix); + (layout.get<style::SymbolAvoidEdges>() || + layout.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line)) { + avoidEdges = collisionIndex.projectTileBoundaries(posMatrix); } - const bool textAllowOverlap = bucket.layout.get<style::TextAllowOverlap>(); - const bool iconAllowOverlap = bucket.layout.get<style::IconAllowOverlap>(); + const bool textAllowOverlap = layout.get<style::TextAllowOverlap>(); + const bool iconAllowOverlap = layout.get<style::IconAllowOverlap>(); // This logic is similar to the "defaultOpacityState" logic below in updateBucketOpacities // If we know a symbol is always supposed to show, force it to be marked visible even if // it wasn't placed into the collision index (because some or all of it was outside the range @@ -165,18 +151,18 @@ void Placement::placeLayerBucket( // This is the reverse of our normal policy of "fade in on pan", but should look like any other // collision and hopefully not be too noticeable. // See https://github.com/mapbox/mapbox-gl-native/issues/12683 - const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.get<style::IconOptional>()); - const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.get<style::TextOptional>()); - std::vector<style::TextVariableAnchorType> variableTextAnchors = bucket.layout.get<style::TextVariableAnchor>(); - const bool rotateWithMap = bucket.layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map; - const bool pitchWithMap = bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map; + const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || layout.get<style::IconOptional>()); + const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || layout.get<style::TextOptional>()); + std::vector<style::TextVariableAnchorType> variableTextAnchors = layout.get<style::TextVariableAnchor>(); + const bool rotateWithMap = layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map; + const bool pitchWithMap = layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map; - const bool zOrderByViewportY = bucket.layout.get<style::SymbolZOrder>() == style::SymbolZOrderType::ViewportY; + const bool zOrderByViewportY = layout.get<style::SymbolZOrder>() == style::SymbolZOrderType::ViewportY; auto placeSymbol = [&] (SymbolInstance& symbolInstance) { if (seenCrossTileIDs.count(symbolInstance.crossTileID) != 0u) return; - if (params.holdingForFade) { + if (renderTile.holdForFade()) { // Mark all symbols from this tile as "not placed", but don't add to seenCrossTileIDs, because we don't // know yet if we have a duplicate in a parent tile that _should_ be placed. placements.emplace(symbolInstance.crossTileID, JointPlacement(false, false, false)); @@ -193,11 +179,11 @@ void Placement::placeLayerBucket( const float fontSize = evaluateSizeForFeature(partiallyEvaluatedTextSize, placedSymbol); if (variableTextAnchors.empty()) { auto placed = collisionIndex.placeFeature(textCollisionFeature, {}, - params.posMatrix, params.textLabelPlaneMatrix, params.pixelRatio, - placedSymbol, params.scale, fontSize, - bucket.layout.get<style::TextAllowOverlap>(), + posMatrix, textLabelPlaneMatrix, pixelRatio, + placedSymbol, scale, fontSize, + layout.get<style::TextAllowOverlap>(), pitchWithMap, - params.showCollisionBoxes, avoidEdges, params.collisionGroup.second); + params.showCollisionBoxes, avoidEdges, collisionGroup.second); placeText = placed.first; offscreen &= placed.second; } else if (!textCollisionFeature.alongLine && !textCollisionFeature.boxes.empty()) { @@ -232,11 +218,11 @@ void Placement::placeLayerBucket( } auto placed = collisionIndex.placeFeature(textCollisionFeature, shift, - params.posMatrix, mat4(), params.pixelRatio, - placedSymbol, params.scale, fontSize, - bucket.layout.get<style::TextAllowOverlap>(), + posMatrix, mat4(), pixelRatio, + placedSymbol, scale, fontSize, + layout.get<style::TextAllowOverlap>(), pitchWithMap, - params.showCollisionBoxes, avoidEdges, params.collisionGroup.second); + params.showCollisionBoxes, avoidEdges, collisionGroup.second); if (placed.first) { assert(symbolInstance.crossTileID != 0u); @@ -287,17 +273,17 @@ void Placement::placeLayerBucket( const float fontSize = evaluateSizeForFeature(partiallyEvaluatedIconSize, placedSymbol); auto placed = collisionIndex.placeFeature(symbolInstance.iconCollisionFeature, {}, - params.posMatrix, params.iconLabelPlaneMatrix, params.pixelRatio, - placedSymbol, params.scale, fontSize, - bucket.layout.get<style::IconAllowOverlap>(), + posMatrix, iconLabelPlaneMatrix, pixelRatio, + placedSymbol, scale, fontSize, + layout.get<style::IconAllowOverlap>(), pitchWithMap, - params.showCollisionBoxes, avoidEdges, params.collisionGroup.second); + params.showCollisionBoxes, avoidEdges, collisionGroup.second); placeIcon = placed.first; offscreen &= placed.second; } - const bool iconWithoutText = !symbolInstance.hasText || bucket.layout.get<style::TextOptional>(); - const bool textWithoutIcon = !symbolInstance.hasIcon || bucket.layout.get<style::IconOptional>(); + const bool iconWithoutText = !symbolInstance.hasText || layout.get<style::TextOptional>(); + const bool textWithoutIcon = !symbolInstance.hasIcon || layout.get<style::IconOptional>(); // combine placements for icon and text if (!iconWithoutText && !textWithoutIcon) { @@ -309,11 +295,11 @@ void Placement::placeLayerBucket( } if (placeText) { - collisionIndex.insertFeature(symbolInstance.textCollisionFeature, bucket.layout.get<style::TextIgnorePlacement>(), bucket.bucketInstanceId, params.collisionGroup.first); + collisionIndex.insertFeature(symbolInstance.textCollisionFeature, layout.get<style::TextIgnorePlacement>(), bucket.bucketInstanceId, collisionGroup.first); } if (placeIcon) { - collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.get<style::IconIgnorePlacement>(), bucket.bucketInstanceId, params.collisionGroup.first); + collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, layout.get<style::IconIgnorePlacement>(), bucket.bucketInstanceId, collisionGroup.first); } assert(symbolInstance.crossTileID != 0); @@ -341,6 +327,12 @@ void Placement::placeLayerBucket( } bucket.justReloaded = false; + + // As long as this placement lives, we have to hold onto this bucket's + // matching FeatureIndex/data for querying purposes + retainedQueryData.emplace(std::piecewise_construct, + std::forward_as_tuple(bucket.bucketInstanceId), + std::forward_as_tuple(bucket.bucketInstanceId, renderTile.getFeatureIndex(), overscaledID)); } void Placement::commit(TimePoint now) { diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index c159286a2b..30062471da 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -90,14 +90,10 @@ private: class BucketPlacementParameters { public: - const mat4& posMatrix; - const mat4& textLabelPlaneMatrix; - const mat4& iconLabelPlaneMatrix; - float scale; - float pixelRatio; + const RenderTile& tile; + const mat4& projMatrix; + std::string sourceId; bool showCollisionBoxes; - bool holdingForFade; - const CollisionGroups::CollisionGroup& collisionGroup; }; class Placement { |