[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.
This commit is contained in:
Mikhail Pozdnyakov
2019-10-02 12:54:30 +03:00
parent 6965fc3100
commit ff6a3ee5b7
2 changed files with 79 additions and 1 deletions

View File

@@ -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));
}
}

View File

@@ -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;