Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] do not render layers that are outside their zoom range
Browse files Browse the repository at this point in the history
So far, we didn't properly disable layers that are outside the zoom range. This means that we rendered layers that should not have been rendered, albeit we didn't make any attempt to load tiles for those layers. However, when zooming in/out, existing tiles might already have been loaded in the source which continued to be rendered. In most cases they weren't actually visible because either the matrices weren't updated, or the clip IDs weren't set so that they would be "rendered" off-screen and clipped completely. In any case, we did way too much work.
  • Loading branch information
kkaefer committed Sep 19, 2016
1 parent 1014a50 commit 9142feb
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/mbgl/style/layer_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class Layer::Impl {
float minZoom = -std::numeric_limits<float>::infinity();
float maxZoom = std::numeric_limits<float>::infinity();
VisibilityType visibility = VisibilityType::Visible;
bool enabled = false;

LayerObserver nullObserver;
LayerObserver* observer = &nullObserver;
Expand Down
25 changes: 21 additions & 4 deletions src/mbgl/style/style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,20 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {

hasPendingTransitions = false;
for (const auto& layer : layers) {
hasPendingTransitions |= layer->baseImpl->recalculate(parameters);
const bool hasTransitions = layer->baseImpl->recalculate(parameters);

Source* source = getSource(layer->baseImpl->source);
if (source && layer->baseImpl->needsRendering(z)) {
// Disable this layer if it doesn't need to be rendered.
const bool needsRendering = layer->baseImpl->needsRendering(z);
if (!needsRendering) {
layer->baseImpl->enabled = false;
continue;
}

hasPendingTransitions |= hasTransitions;
layer->baseImpl->enabled = true;

// If this layer has a source, make sure that it gets loaded.
if (Source* source = getSource(layer->baseImpl->source)) {
source->baseImpl->enabled = true;
if (!source->baseImpl->loaded) {
source->baseImpl->loadDescription(fileSource);
Expand Down Expand Up @@ -319,8 +329,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
}

for (const auto& layer : layers) {
if (layer->baseImpl->visibility == VisibilityType::None)
if (!layer->baseImpl->enabled) {
continue;
}

if (const BackgroundLayer* background = layer->as<BackgroundLayer>()) {
if (debugOptions & MapDebugOptions::Overdraw) {
Expand Down Expand Up @@ -400,6 +411,9 @@ std::vector<Feature> Style::queryRenderedFeatures(const QueryParameters& paramet

// Combine all results based on the style layer order.
for (const auto& layer : layers) {
if (!layer->baseImpl->enabled) {
continue;
}
auto it = resultsByLayer.find(layer->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
Expand All @@ -412,6 +426,9 @@ std::vector<Feature> Style::queryRenderedFeatures(const QueryParameters& paramet
float Style::getQueryRadius() const {
float additionalRadius = 0;
for (auto& layer : layers) {
if (!layer->baseImpl->enabled) {
continue;
}
additionalRadius = util::max(additionalRadius, layer->baseImpl->getQueryRadius());
}
return additionalRadius;
Expand Down
Binary file added test/fixtures/map/disabled_layers/first/expected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/map/disabled_layers/tile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions test/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,67 @@ TEST(Map, RemoveLayer) {
test::checkImage("test/fixtures/map/remove_layer", test::render(map));
}

TEST(Map, DisabledSources) {
MapTest test;

// Always load the same image tile for raster layers.
test.fileSource.response = [] (const Resource& res) -> optional<Response> {
if (res.url == "asset://tile.png") {
Response response;
response.data = std::make_shared<std::string>(
util::read_file("test/fixtures/map/disabled_layers/tile.png"));
return {std::move(response)};
}
return {};
};

Map map(test.view, test.fileSource, MapMode::Still);
map.setZoom(1);

// This stylesheet has two raster layers, one that starts at zoom 1, the other at zoom 0.
// We first render a map at zoom level 1, which should show both layers (both are "visible" due
// to an opacity of 0.5). Then, we are zooming back out to a zoom level of 0.5 and rerender.
// The "raster1" layer should not be visible anymore since it has minzoom 1, while "raster2"
// should still be there. Both layers have a distinct color through "raster-hue-rotate".
map.setStyleJSON(R"STYLE(
{
"version": 8,
"name": "Test",
"sources": {
"raster": {
"type": "raster",
"tiles": [ "asset://tile.png" ],
"tileSize": 256
}
},
"layers": [{
"id": "background",
"type": "background",
"paint": {
"background-color": "white"
}
}, {
"id": "raster1",
"type": "raster",
"source": "raster",
"minzoom": 0
}, {
"id": "raster2",
"type": "raster",
"source": "raster",
"minzoom": 1,
"paint": {
"raster-hue-rotate": 180
}
}]
}
)STYLE");

test::checkImage("test/fixtures/map/disabled_layers/first", test::render(map));
map.setZoom(0.5);
test::checkImage("test/fixtures/map/disabled_layers/second", test::render(map));
}

TEST(Map, Classes) {
MapTest test;

Expand Down

0 comments on commit 9142feb

Please sign in to comment.