summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-10-02 12:54:30 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-10-02 20:45:46 +0300
commitff6a3ee5b7fea7f4c18fed3480308c34fd434ed6 (patch)
tree46dad3916a6a76b53b77dcee40f8c9619b46c9f9
parent6965fc310042dd6afd07e03baf9aff67d0f97ab6 (diff)
downloadqtlocation-mapboxgl-ff6a3ee5b7fea7f4c18fed3480308c34fd434ed6.tar.gz
[core] Suppress network requests for invisible tiles
If the render source does not need rendering, we set necessity for its tiles to `optional`, and thus suppress network requests on tiles expiration.
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp4
-rw-r--r--test/style/source.test.cpp76
2 files changed, 79 insertions, 1 deletions
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index 2bf6e2e1a9..586d3b5a8a 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -68,6 +68,10 @@ void TilePyramid::update(const std::vector<Immutable<style::LayerProperties>>& l
if (!needsRendering) {
if (!needsRelayout) {
for (auto& entry : tiles) {
+ // These tiles are invisible, we set optional necessity
+ // for them and thus suppress network requests on
+ // tiles expiration (see `OnlineFileRequest`).
+ entry.second->setNecessity(TileNecessity::Optional);
cache.add(entry.first, std::move(entry.second));
}
}
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index ca0e79f46a..a08d11c7ad 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -35,10 +35,11 @@
#include <mbgl/util/optional.hpp>
#include <mbgl/util/range.hpp>
-#include <mbgl/map/transform.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/annotation/annotation_source.hpp>
+#include <mbgl/map/transform.hpp>
#include <mbgl/renderer/image_manager.hpp>
+#include <mbgl/renderer/tile_render_data.hpp>
#include <mbgl/text/glyph_manager.hpp>
#include <cstdint>
@@ -793,6 +794,79 @@ TEST(Source, CustomGeometrySourceSetTileData) {
test.run();
}
+namespace {
+
+class FakeTileSource;
+
+class FakeTile : public Tile {
+public:
+ FakeTile(FakeTileSource& source_, const OverscaledTileID& tileID)
+ : Tile(Tile::Kind::Geometry, tileID), source(source_) {
+ renderable = true;
+ }
+ void setNecessity(TileNecessity necessity) override;
+ bool layerPropertiesUpdated(const Immutable<style::LayerProperties>&) override { return true; }
+
+ std::unique_ptr<TileRenderData> createRenderData() override { return nullptr; }
+
+private:
+ FakeTileSource& source;
+};
+
+class FakeTileSource : public RenderTileSetSource {
+public:
+ MOCK_METHOD1(tileSetNecessity, void(TileNecessity));
+
+ explicit FakeTileSource(Immutable<style::Source::Impl> impl_) : RenderTileSetSource(std::move(impl_)) {}
+ void updateInternal(const Tileset& tileset,
+ const std::vector<Immutable<style::LayerProperties>>& layers,
+ const bool needsRendering,
+ const bool needsRelayout,
+ const TileParameters& parameters) override {
+ tilePyramid.update(layers,
+ needsRendering,
+ needsRelayout,
+ parameters,
+ SourceType::Vector,
+ util::tileSize,
+ tileset.zoomRange,
+ tileset.bounds,
+ [&](const OverscaledTileID& tileID) { return std::make_unique<FakeTile>(*this, tileID); });
+ }
+
+ const optional<Tileset>& getTileset() const override {
+ return static_cast<const style::VectorSource::Impl&>(*baseImpl).tileset;
+ }
+};
+
+void FakeTile::setNecessity(TileNecessity necessity) {
+ source.tileSetNecessity(necessity);
+}
+
+} // namespace
+
+TEST(Source, InvisibleSourcesTileNecessity) {
+ SourceTest test;
+ VectorSource initialized("source", Tileset{{"tiles"}});
+ initialized.loadDescription(*test.fileSource);
+
+ FakeTileSource renderTilesetSource{initialized.baseImpl};
+ RenderSource* renderSource = &renderTilesetSource;
+ LineLayer layer("id", "source");
+ Immutable<LayerProperties> layerProperties =
+ makeMutable<LineLayerProperties>(staticImmutableCast<LineLayer::Impl>(layer.baseImpl));
+ std::vector<Immutable<LayerProperties>> layers{layerProperties};
+ EXPECT_CALL(renderTilesetSource, tileSetNecessity(TileNecessity::Required)).Times(1);
+ renderSource->update(initialized.baseImpl, layers, true, true, test.tileParameters);
+
+ // Necessity for invisible tiles must be set to `optional`.
+ EXPECT_CALL(renderTilesetSource, tileSetNecessity(TileNecessity::Optional)).Times(1);
+ renderSource->update(initialized.baseImpl, layers, false, false, test.tileParameters);
+
+ // Necessity is again `required` once tiles get back visible.
+ EXPECT_CALL(renderTilesetSource, tileSetNecessity(TileNecessity::Required)).Times(1);
+ renderSource->update(initialized.baseImpl, layers, true, false, test.tileParameters);
+}
TEST(Source, RenderTileSetSourceUpdate) {
SourceTest test;