diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-10-02 15:31:03 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@gmail.com> | 2017-10-03 13:41:09 -0700 |
commit | ac64a4a660a6f2bc4ac2c81895620b1061cb5ff5 (patch) | |
tree | af2480db8a69e5c317b27637d182d8f8b1cf9dcb | |
parent | ce4cc65486b9676cfecb7e771ff8af3db2b9d408 (diff) | |
download | qtlocation-mapboxgl-upstream/collision-placement.tar.gz |
Initial implementation of "PlacementState": intended to be used by renderer to pause and restart placement.upstream/collision-placement
-rw-r--r-- | cmake/core-files.cmake | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/placement_state.cpp | 103 | ||||
-rw-r--r-- | src/mbgl/renderer/placement_state.hpp | 70 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/tile/tile.hpp | 7 |
5 files changed, 185 insertions, 0 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 2eadc747d1..4d10952da5 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -179,6 +179,8 @@ set(MBGL_CORE_FILES src/mbgl/renderer/paint_parameters.hpp src/mbgl/renderer/paint_property_binder.hpp src/mbgl/renderer/paint_property_statistics.hpp + src/mbgl/renderer/placement_state.hpp + src/mbgl/renderer/placement_state.cpp src/mbgl/renderer/possibly_evaluated_property_value.hpp src/mbgl/renderer/property_evaluation_parameters.hpp src/mbgl/renderer/property_evaluator.hpp diff --git a/src/mbgl/renderer/placement_state.cpp b/src/mbgl/renderer/placement_state.cpp new file mode 100644 index 0000000000..f00001ec23 --- /dev/null +++ b/src/mbgl/renderer/placement_state.cpp @@ -0,0 +1,103 @@ +#include <mbgl/renderer/placement_state.hpp> +#include <mbgl/renderer/layers/render_symbol_layer.hpp> +#include <mbgl/renderer/render_layer.hpp> +#include <mbgl/renderer/render_source.hpp> +#include <mbgl/renderer/render_tile.hpp> +#include <mbgl/tile/tile.hpp> + + +namespace mbgl { + +LayerPlacementState::LayerPlacementState() : currentTileIndex(0) +{ +} + +bool LayerPlacementState::continuePlacement(RenderSymbolLayer& layer, + CollisionIndex& collisionIndex, + const bool showCollisionBoxes, + std::function<bool()> shouldPausePlacement) { + while (currentTileIndex < layer.renderTiles.size()) { + RenderTile& tile = layer.renderTiles[currentTileIndex++]; + tile.tile.placeLayer(showCollisionBoxes, collisionIndex, layer.impl()); + + if (shouldPausePlacement()) { + return true; + } + } + return false; +} + +PlacementState::PlacementState(const TransformState& transformState, + const std::vector<RenderLayer>& order, + const bool forceFullPlacement_, + const bool showCollisionBoxes_, + Duration fadeDuration, + optional<PlacementState>& previousPlacement) + : collisionIndex(transformState) + , currentLayerIndex(order.size() - 1) + , forceFullPlacement(forceFullPlacement_) + , showCollisionBoxes(showCollisionBoxes_) +{ + if (forceFullPlacement || !previousPlacement) { + delayUntil = TimePoint(); + } else { + delayUntil = previousPlacement->delayUntil + Milliseconds(300); + } + + if (previousPlacement) { + collisionFadeTimes = previousPlacement->collisionFadeTimes; + } else { + collisionFadeTimes = { TimePoint::min(), fadeDuration }; + } +} + +void PlacementState::continuePlacement(std::vector<RenderLayer>& order, std::vector<RenderSource>& sources) { + const TimePoint startTime; + + if (startTime < delayUntil) return; + + auto shouldPausePlacement = [&] () { + const Duration elapsedTime = TimePoint() - startTime; + return forceFullPlacement ? false : elapsedTime > Milliseconds(2); + }; + + do { + RenderLayer& renderLayer = order[currentLayerIndex]; + if (renderLayer.is<RenderSymbolLayer>()) { + if (inProgressLayer) { + inProgressLayer = LayerPlacementState(); + } + + bool pausePlacement = inProgressLayer->continuePlacement(*renderLayer.as<RenderSymbolLayer>(), + collisionIndex, + showCollisionBoxes, + shouldPausePlacement); + + if (pausePlacement) { + // We didn't finish placing all layers within 2ms, + // but we can keep rendering with a partial placement + // We'll resume here on the next frame + return; + } + + inProgressLayer = std::experimental::nullopt; + } + + currentLayerIndex--; + } while (currentLayerIndex > 0); + + for (RenderSource& source : sources) { + auto tiles = source.getRenderTiles(); + for (RenderTile& tile : tiles) { + tile.tile.commitPlacement(collisionIndex, collisionFadeTimes); + } + } + + done = true; +} + +bool PlacementState::stillFading() const { + return TimePoint() < collisionFadeTimes.latestStart + collisionFadeTimes.fadeDuration; +} + +}; // mbgl diff --git a/src/mbgl/renderer/placement_state.hpp b/src/mbgl/renderer/placement_state.hpp new file mode 100644 index 0000000000..07c655ca03 --- /dev/null +++ b/src/mbgl/renderer/placement_state.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include <mbgl/map/transform_state.hpp> +#include <mbgl/style/collection.hpp> +#include <mbgl/style/layer.hpp> +#include <mbgl/tile/tile_id.hpp> +#include <mbgl/util/chrono.hpp> +#include <mbgl/util/optional.hpp> + +#include <functional> +#include <map> +#include <string> + +namespace mbgl { + +// TODO: Placeholder +class CollisionIndex { +public: + CollisionIndex(const TransformState&) {} +}; + +class RenderLayer; +class RenderSymbolLayer; +class RenderSource; + +struct CollisionFadeTimes { + TimePoint latestStart; + Duration fadeDuration; +}; + +class LayerPlacementState { +public: + LayerPlacementState(); + bool continuePlacement(RenderSymbolLayer& renderLayer, + CollisionIndex& collisionIndex, + const bool showCollisionBoxes, + std::function<bool()> shouldPausePlacement); + +private: + size_t currentTileIndex; +}; + +class PlacementState +{ +public: + PlacementState(const TransformState& transformState, + const std::vector<RenderLayer>& order, + const bool forceFullPlacement, + const bool showCollisionBoxes, + Duration fadeDuration, + optional<PlacementState>& previousPlacement); + + bool isDone() const { return done; } + bool stillFading() const; + + void continuePlacement(std::vector<RenderLayer>& order, std::vector<RenderSource>& sources); + +private: + CollisionIndex collisionIndex; + bool done; + size_t currentLayerIndex; + bool forceFullPlacement; + bool showCollisionBoxes; + TimePoint delayUntil; + CollisionFadeTimes collisionFadeTimes; + optional<LayerPlacementState> inProgressLayer; + +}; + +}; // mbgl diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index dfc6bcf2fd..afd1e9546b 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -86,6 +86,9 @@ protected: // evaluated StyleProperties object and is updated accordingly. RenderPass passes = RenderPass::None; + // TODO: Placement needs access to the renderTiles -- figure out how best to coordinate + friend class LayerPlacementState; + //Stores current set of tiles to be rendered for this layer. std::vector<std::reference_wrapper<RenderTile>> renderTiles; diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 39cc0de8bd..eb6ad0c128 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -27,6 +27,9 @@ class RenderLayer; class RenderedQueryOptions; class SourceQueryOptions; +class CollisionIndex; +struct CollisionFadeTimes; + namespace gl { class Context; } // namespace gl @@ -57,6 +60,10 @@ public: virtual void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) {} virtual void setMask(TileMask&&) {} + // TODO: Implement + virtual void placeLayer(const bool, CollisionIndex& , const style::Layer::Impl&) {}; + virtual void commitPlacement(const CollisionIndex&, CollisionFadeTimes&) {}; + virtual void queryRenderedFeatures( std::unordered_map<std::string, std::vector<Feature>>& result, const GeometryCoordinates& queryGeometry, |