summaryrefslogtreecommitdiff
path: root/src/mbgl/tile/geometry_tile.cpp
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <tmpsantos@gmail.com>2017-08-07 19:19:32 +0300
committerThiago Marcos P. Santos <tmpsantos@gmail.com>2017-08-09 18:02:46 +0300
commitc53896caefc96a8c18ab746026330ddc4fc0338e (patch)
tree8f562b0c416d6c99f7b565e58b758701f6081677 /src/mbgl/tile/geometry_tile.cpp
parent9ecbe3642fb4a53b558598239b59bf1d0224c25b (diff)
downloadqtlocation-mapboxgl-c53896caefc96a8c18ab746026330ddc4fc0338e.tar.gz
Bump Mapbox GL Nativeqt-v1.1.0
mapbox-gl-native @ edd7948893fcd40a24d96b790e21d3dd028cecbe
Diffstat (limited to 'src/mbgl/tile/geometry_tile.cpp')
-rw-r--r--src/mbgl/tile/geometry_tile.cpp202
1 files changed, 160 insertions, 42 deletions
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 9aeb35c821..33911df9ed 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -2,17 +2,27 @@
#include <mbgl/tile/geometry_tile_worker.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/tile/tile_observer.hpp>
-#include <mbgl/style/update_parameters.hpp>
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
-#include <mbgl/style/layers/symbol_layer.hpp>
-#include <mbgl/style/style.hpp>
+#include <mbgl/renderer/tile_parameters.hpp>
+#include <mbgl/renderer/layers/render_background_layer.hpp>
+#include <mbgl/renderer/layers/render_custom_layer.hpp>
+#include <mbgl/renderer/layers/render_symbol_layer.hpp>
+#include <mbgl/renderer/buckets/symbol_bucket.hpp>
+#include <mbgl/renderer/query.hpp>
+#include <mbgl/text/glyph_atlas.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/run_loop.hpp>
+#include <mbgl/style/filter_evaluator.hpp>
+#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/logging.hpp>
+
+#include <iostream>
namespace mbgl {
@@ -20,41 +30,49 @@ using namespace style;
GeometryTile::GeometryTile(const OverscaledTileID& id_,
std::string sourceID_,
- const style::UpdateParameters& parameters)
+ const TileParameters& parameters)
: Tile(id_),
sourceID(std::move(sourceID_)),
- style(parameters.style),
mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())),
worker(parameters.workerScheduler,
ActorRef<GeometryTile>(*this, mailbox),
id_,
- *parameters.style.glyphAtlas,
obsolete,
- parameters.mode) {
+ parameters.mode,
+ parameters.pixelRatio),
+ glyphManager(parameters.glyphManager),
+ imageManager(parameters.imageManager),
+ placementThrottler(Milliseconds(300), [this] { invokePlacement(); }),
+ lastYStretch(1.0f) {
}
GeometryTile::~GeometryTile() {
- cancel();
+ glyphManager.removeRequestor(*this);
+ imageManager.removeRequestor(*this);
+ markObsolete();
}
void GeometryTile::cancel() {
+ markObsolete();
+}
+
+void GeometryTile::markObsolete() {
obsolete = true;
}
void GeometryTile::setError(std::exception_ptr err) {
+ loaded = true;
+ renderable = false;
observer->onTileError(*this, err);
}
void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
// state despite pending parse operations.
- if (availableData == DataAvailability::All) {
- availableData = DataAvailability::Some;
- }
+ pending = true;
++correlationID;
worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
- redoLayout();
}
void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
@@ -64,71 +82,126 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
// state despite pending parse operations.
- if (availableData == DataAvailability::All) {
- availableData = DataAvailability::Some;
- }
+ pending = true;
++correlationID;
requestedConfig = desiredConfig;
- worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID);
+ placementThrottler.invoke();
}
-void GeometryTile::symbolDependenciesChanged() {
- worker.invoke(&GeometryTileWorker::symbolDependenciesChanged);
+void GeometryTile::invokePlacement() {
+ if (requestedConfig) {
+ worker.invoke(&GeometryTileWorker::setPlacementConfig, *requestedConfig, correlationID);
+ }
}
-void GeometryTile::redoLayout() {
+void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
// state despite pending parse operations.
- if (availableData == DataAvailability::All) {
- availableData = DataAvailability::Some;
- }
+ pending = true;
- std::vector<std::unique_ptr<Layer>> copy;
+ std::vector<Immutable<Layer::Impl>> impls;
- for (const Layer* layer : style.getLayers()) {
- // Avoid cloning and including irrelevant layers.
- if (layer->is<BackgroundLayer>() ||
- layer->is<CustomLayer>() ||
- layer->baseImpl->source != sourceID ||
- id.overscaledZ < std::floor(layer->baseImpl->minZoom) ||
- id.overscaledZ >= std::ceil(layer->baseImpl->maxZoom) ||
- layer->baseImpl->visibility == VisibilityType::None) {
+ for (const auto& layer : layers) {
+ // Skip irrelevant layers.
+ if (layer->type == LayerType::Background ||
+ layer->type == LayerType::Custom ||
+ layer->source != sourceID ||
+ id.overscaledZ < std::floor(layer->minZoom) ||
+ id.overscaledZ >= std::ceil(layer->maxZoom) ||
+ layer->visibility == VisibilityType::None) {
continue;
}
- copy.push_back(layer->baseImpl->clone());
+ impls.push_back(layer);
}
++correlationID;
- worker.invoke(&GeometryTileWorker::setLayers, std::move(copy), correlationID);
+ worker.invoke(&GeometryTileWorker::setLayers, std::move(impls), correlationID);
}
void GeometryTile::onLayout(LayoutResult result) {
- availableData = DataAvailability::Some;
+ loaded = true;
+ renderable = true;
nonSymbolBuckets = std::move(result.nonSymbolBuckets);
featureIndex = std::move(result.featureIndex);
data = std::move(result.tileData);
+ collisionTile.reset();
observer->onTileChanged(*this);
}
void GeometryTile::onPlacement(PlacementResult result) {
+ loaded = true;
+ renderable = true;
if (result.correlationID == correlationID) {
- availableData = DataAvailability::All;
+ pending = false;
}
symbolBuckets = std::move(result.symbolBuckets);
collisionTile = std::move(result.collisionTile);
+ if (result.glyphAtlasImage) {
+ glyphAtlasImage = std::move(*result.glyphAtlasImage);
+ }
+ if (result.iconAtlasImage) {
+ iconAtlasImage = std::move(*result.iconAtlasImage);
+ }
+ if (collisionTile.get()) {
+ lastYStretch = collisionTile->yStretch;
+ }
observer->onTileChanged(*this);
}
void GeometryTile::onError(std::exception_ptr err) {
- availableData = DataAvailability::All;
+ loaded = true;
+ pending = false;
+ renderable = false;
observer->onTileError(*this, err);
}
+
+void GeometryTile::onGlyphsAvailable(GlyphMap glyphs) {
+ worker.invoke(&GeometryTileWorker::onGlyphsAvailable, std::move(glyphs));
+}
+
+void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) {
+ glyphManager.getGlyphs(*this, std::move(glyphDependencies));
+}
+
+void GeometryTile::onImagesAvailable(ImageMap images) {
+ worker.invoke(&GeometryTileWorker::onImagesAvailable, std::move(images));
+}
+
+void GeometryTile::getImages(ImageDependencies imageDependencies) {
+ imageManager.getImages(*this, std::move(imageDependencies));
+}
+
+void GeometryTile::upload(gl::Context& context) {
+ auto uploadFn = [&] (Bucket& bucket) {
+ if (bucket.needsUpload()) {
+ bucket.upload(context);
+ }
+ };
+
+ for (auto& entry : nonSymbolBuckets) {
+ uploadFn(*entry.second);
+ }
+
+ for (auto& entry : symbolBuckets) {
+ uploadFn(*entry.second);
+ }
+
+ if (glyphAtlasImage) {
+ glyphAtlasTexture = context.createTexture(*glyphAtlasImage, 0);
+ glyphAtlasImage = {};
+ }
+
+ if (iconAtlasImage) {
+ iconAtlasTexture = context.createTexture(*iconAtlasImage, 0);
+ iconAtlasImage = {};
+ }
+}
-Bucket* GeometryTile::getBucket(const Layer& layer) {
- const auto& buckets = layer.is<SymbolLayer>() ? symbolBuckets : nonSymbolBuckets;
- const auto it = buckets.find(layer.baseImpl->id);
+Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
+ const auto& buckets = layer.type == LayerType::Symbol ? symbolBuckets : nonSymbolBuckets;
+ const auto it = buckets.find(layer.id);
if (it == buckets.end()) {
return nullptr;
}
@@ -141,7 +214,8 @@ void GeometryTile::queryRenderedFeatures(
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry,
const TransformState& transformState,
- const optional<std::vector<std::string>>& layerIDs) {
+ const RenderStyle& style,
+ const RenderedQueryOptions& options) {
if (!featureIndex || !data) return;
@@ -150,11 +224,55 @@ void GeometryTile::queryRenderedFeatures(
transformState.getAngle(),
util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ),
- layerIDs,
+ options,
*data,
id.canonical,
style,
- collisionTile.get());
+ collisionTile.get(),
+ *this);
+}
+
+void GeometryTile::querySourceFeatures(
+ std::vector<Feature>& result,
+ const SourceQueryOptions& options) {
+
+ // Data not yet available
+ if (!data) {
+ return;
+ }
+
+ // No source layers, specified, nothing to do
+ if (!options.sourceLayers) {
+ Log::Warning(Event::General, "At least one sourceLayer required");
+ return;
+ }
+
+ for (auto sourceLayer : *options.sourceLayers) {
+ // Go throught all sourceLayers, if any
+ // to gather all the features
+ auto layer = data->getLayer(sourceLayer);
+
+ if (layer) {
+ auto featureCount = layer->featureCount();
+ for (std::size_t i = 0; i < featureCount; i++) {
+ auto feature = layer->getFeature(i);
+
+ // Apply filter, if any
+ if (options.filter && !(*options.filter)(*feature)) {
+ continue;
+ }
+
+ result.push_back(convertFeature(*feature, id.canonical));
+ }
+ }
+ }
+}
+
+float GeometryTile::yStretch() const {
+ // collisionTile gets reset in onLayout but we don't clear the symbolBuckets
+ // until a new placement result comes along, so keep the yStretch value in
+ // case we need to render them.
+ return lastYStretch;
}
} // namespace mbgl