summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-10-02 15:31:03 -0700
committerChris Loer <chris.loer@gmail.com>2017-10-03 13:41:09 -0700
commitac64a4a660a6f2bc4ac2c81895620b1061cb5ff5 (patch)
treeaf2480db8a69e5c317b27637d182d8f8b1cf9dcb
parentce4cc65486b9676cfecb7e771ff8af3db2b9d408 (diff)
downloadqtlocation-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.cmake2
-rw-r--r--src/mbgl/renderer/placement_state.cpp103
-rw-r--r--src/mbgl/renderer/placement_state.hpp70
-rw-r--r--src/mbgl/renderer/render_layer.hpp3
-rw-r--r--src/mbgl/tile/tile.hpp7
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,