summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.cpp6
-rw-r--r--src/mbgl/renderer/buckets/raster_bucket.cpp13
-rw-r--r--src/mbgl/renderer/image_manager.cpp21
-rw-r--r--src/mbgl/renderer/image_manager.hpp8
-rw-r--r--src/mbgl/renderer/layers/render_custom_layer.cpp8
-rw-r--r--src/mbgl/renderer/layers/render_custom_layer.hpp5
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp194
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp4
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp54
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp17
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp8
-rw-r--r--src/mbgl/renderer/render_item.hpp36
-rw-r--r--src/mbgl/renderer/render_pass.hpp1
-rw-r--r--src/mbgl/renderer/render_source.hpp3
-rw-r--r--src/mbgl/renderer/render_static_data.cpp6
-rw-r--r--src/mbgl/renderer/render_static_data.hpp5
-rw-r--r--src/mbgl/renderer/render_style.cpp449
-rw-r--r--src/mbgl/renderer/render_style.hpp92
-rw-r--r--src/mbgl/renderer/render_style_observer.hpp14
-rw-r--r--src/mbgl/renderer/render_tile.cpp86
-rw-r--r--src/mbgl/renderer/renderer.cpp12
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp579
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp70
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.cpp24
-rw-r--r--src/mbgl/renderer/sources/render_geojson_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_image_source.cpp9
-rw-r--r--src/mbgl/renderer/sources/render_image_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.cpp2
-rw-r--r--src/mbgl/renderer/sources/render_raster_source.hpp2
-rw-r--r--src/mbgl/renderer/sources/render_vector_source.cpp4
-rw-r--r--src/mbgl/renderer/sources/render_vector_source.hpp2
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp45
-rw-r--r--src/mbgl/renderer/tile_pyramid.hpp6
-rw-r--r--src/mbgl/renderer/update_parameters.hpp4
34 files changed, 830 insertions, 963 deletions
diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp
index 194b012eee..a96518df38 100644
--- a/src/mbgl/renderer/buckets/line_bucket.cpp
+++ b/src/mbgl/renderer/buckets/line_bucket.cpp
@@ -401,7 +401,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
Point<double> extrude = normal;
if (endLeft)
extrude = extrude - (util::perp(normal) * endLeft);
- vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, false }, endLeft, distance * LINE_DISTANCE_SCALE));
+ vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, false, endLeft, distance * LINE_DISTANCE_SCALE));
e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
@@ -412,7 +412,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
extrude = normal * -1.0;
if (endRight)
extrude = extrude - (util::perp(normal) * endRight);
- vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, true }, -endRight, distance * LINE_DISTANCE_SCALE));
+ vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, true, -endRight, distance * LINE_DISTANCE_SCALE));
e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
@@ -437,7 +437,7 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
- vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, { false, lineTurnsLeft }, 0, distance * LINE_DISTANCE_SCALE));
+ vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, false, lineTurnsLeft, 0, distance * LINE_DISTANCE_SCALE));
e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
diff --git a/src/mbgl/renderer/buckets/raster_bucket.cpp b/src/mbgl/renderer/buckets/raster_bucket.cpp
index 1a0409f456..a66dd42d74 100644
--- a/src/mbgl/renderer/buckets/raster_bucket.cpp
+++ b/src/mbgl/renderer/buckets/raster_bucket.cpp
@@ -69,16 +69,11 @@ void RasterBucket::setMask(TileMask&& mask_) {
for (const auto& id : mask) {
// Create a quad for every masked tile.
const int32_t vertexExtent = util::EXTENT >> id.z;
- const int32_t textureExtent = 32768 >> id.z;
const Point<int16_t> tlVertex = { static_cast<int16_t>(id.x * vertexExtent),
static_cast<int16_t>(id.y * vertexExtent) };
const Point<int16_t> brVertex = { static_cast<int16_t>(tlVertex.x + vertexExtent),
static_cast<int16_t>(tlVertex.y + vertexExtent) };
- const Point<uint16_t> tlTexture = { static_cast<uint16_t>(id.x * textureExtent),
- static_cast<uint16_t>(id.y * textureExtent) };
- const Point<uint16_t> brTexture = { static_cast<uint16_t>(tlTexture.x + textureExtent),
- static_cast<uint16_t>(tlTexture.y + textureExtent) };
if (segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
// Move to a new segments because the old one can't hold the geometry.
@@ -86,13 +81,13 @@ void RasterBucket::setMask(TileMask&& mask_) {
}
vertices.emplace_back(
- RasterProgram::layoutVertex({ tlVertex.x, tlVertex.y }, { tlTexture.x, tlTexture.y }));
+ RasterProgram::layoutVertex({ tlVertex.x, tlVertex.y }, { static_cast<uint16_t>(tlVertex.x), static_cast<uint16_t>(tlVertex.y) }));
vertices.emplace_back(
- RasterProgram::layoutVertex({ brVertex.x, tlVertex.y }, { brTexture.x, tlTexture.y }));
+ RasterProgram::layoutVertex({ brVertex.x, tlVertex.y }, { static_cast<uint16_t>(brVertex.x), static_cast<uint16_t>(tlVertex.y) }));
vertices.emplace_back(
- RasterProgram::layoutVertex({ tlVertex.x, brVertex.y }, { tlTexture.x, brTexture.y }));
+ RasterProgram::layoutVertex({ tlVertex.x, brVertex.y }, { static_cast<uint16_t>(tlVertex.x), static_cast<uint16_t>(brVertex.y) }));
vertices.emplace_back(
- RasterProgram::layoutVertex({ brVertex.x, brVertex.y }, { brTexture.x, brTexture.y }));
+ RasterProgram::layoutVertex({ brVertex.x, brVertex.y }, { static_cast<uint16_t>(brVertex.x), static_cast<uint16_t>(brVertex.y) }));
auto& segment = segments.back();
assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp
index 692747bca4..2ef6be0c4f 100644
--- a/src/mbgl/renderer/image_manager.cpp
+++ b/src/mbgl/renderer/image_manager.cpp
@@ -39,6 +39,13 @@ void ImageManager::removeImage(const std::string& id) {
auto it = patterns.find(id);
if (it != patterns.end()) {
+ // Clear pattern from the atlas image.
+ const uint32_t x = it->second.bin->x;
+ const uint32_t y = it->second.bin->y;
+ const uint32_t w = it->second.bin->w;
+ const uint32_t h = it->second.bin->h;
+ PremultipliedImage::clear(atlasImage, { x, y }, { w, h });
+
shelfPack.unref(*it->second.bin);
patterns.erase(it);
}
@@ -52,23 +59,23 @@ const style::Image::Impl* ImageManager::getImage(const std::string& id) const {
return nullptr;
}
-void ImageManager::getImages(ImageRequestor& requestor, ImageDependencies dependencies) {
+void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) {
// If the sprite has been loaded, or if all the icon dependencies are already present
// (i.e. if they've been addeded via runtime styling), then notify the requestor immediately.
// Otherwise, delay notification until the sprite is loaded. At that point, if any of the
// dependencies are still unavailable, we'll just assume they are permanently missing.
bool hasAllDependencies = true;
if (!isLoaded()) {
- for (const auto& dependency : dependencies) {
+ for (const auto& dependency : pair.first) {
if (images.find(dependency) == images.end()) {
hasAllDependencies = false;
}
}
}
if (isLoaded() || hasAllDependencies) {
- notify(requestor, dependencies);
+ notify(requestor, std::move(pair));
} else {
- requestors.emplace(&requestor, std::move(dependencies));
+ requestors.emplace(&requestor, std::move(pair));
}
}
@@ -76,17 +83,17 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) {
requestors.erase(&requestor);
}
-void ImageManager::notify(ImageRequestor& requestor, const ImageDependencies& dependencies) const {
+void ImageManager::notify(ImageRequestor& requestor, const ImageRequestPair& pair) const {
ImageMap response;
- for (const auto& dependency : dependencies) {
+ for (const auto& dependency : pair.first) {
auto it = images.find(dependency);
if (it != images.end()) {
response.emplace(*it);
}
}
- requestor.onImagesAvailable(response);
+ requestor.onImagesAvailable(response, pair.second);
}
void ImageManager::dumpDebugLogs() const {
diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp
index 1c9d67f47d..f72ba9fb53 100644
--- a/src/mbgl/renderer/image_manager.hpp
+++ b/src/mbgl/renderer/image_manager.hpp
@@ -21,7 +21,7 @@ class Context;
class ImageRequestor {
public:
virtual ~ImageRequestor() = default;
- virtual void onImagesAvailable(ImageMap) = 0;
+ virtual void onImagesAvailable(ImageMap, uint64_t imageCorrelationID) = 0;
};
/*
@@ -50,15 +50,15 @@ public:
void updateImage(Immutable<style::Image::Impl>);
void removeImage(const std::string&);
- void getImages(ImageRequestor&, ImageDependencies);
+ void getImages(ImageRequestor&, ImageRequestPair&&);
void removeRequestor(ImageRequestor&);
private:
- void notify(ImageRequestor&, const ImageDependencies&) const;
+ void notify(ImageRequestor&, const ImageRequestPair&) const;
bool loaded = false;
- std::unordered_map<ImageRequestor*, ImageDependencies> requestors;
+ std::unordered_map<ImageRequestor*, ImageRequestPair> requestors;
ImageMap images;
// Pattern stuff
diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp
index ae0c4b026b..7ece3970da 100644
--- a/src/mbgl/renderer/layers/render_custom_layer.cpp
+++ b/src/mbgl/renderer/layers/render_custom_layer.cpp
@@ -16,8 +16,12 @@ RenderCustomLayer::RenderCustomLayer(Immutable<style::CustomLayer::Impl> _impl)
RenderCustomLayer::~RenderCustomLayer() {
assert(BackendScope::exists());
- if (initialized && impl().deinitializeFn) {
- impl().deinitializeFn(impl().context);
+ if (initialized) {
+ if (contextDestroyed && impl().contextLostFn ) {
+ impl().contextLostFn(impl().context);
+ } else if (!contextDestroyed && impl().deinitializeFn) {
+ impl().deinitializeFn(impl().context);
+ }
}
}
diff --git a/src/mbgl/renderer/layers/render_custom_layer.hpp b/src/mbgl/renderer/layers/render_custom_layer.hpp
index d8e9d93811..32ed9da8da 100644
--- a/src/mbgl/renderer/layers/render_custom_layer.hpp
+++ b/src/mbgl/renderer/layers/render_custom_layer.hpp
@@ -19,8 +19,13 @@ public:
const style::CustomLayer::Impl& impl() const;
+ void markContextDestroyed() {
+ contextDestroyed = true;
+ };
+
private:
bool initialized = false;
+ bool contextDestroyed = false;
};
template <>
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index 6295f62b21..fbd6160e8a 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -37,8 +37,9 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters
void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluated = unevaluated.evaluate(parameters);
- passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? RenderPass::Translucent
- : RenderPass::None;
+ passes = (evaluated.get<style::FillExtrusionOpacity>() > 0)
+ ? (RenderPass::Translucent | RenderPass::Pass3D)
+ : RenderPass::None;
}
bool RenderFillExtrusionLayer::hasTransition() const {
@@ -50,113 +51,100 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*
return;
}
- const auto size = parameters.context.viewport.getCurrentValue().size;
+ if (parameters.pass == RenderPass::Pass3D) {
+ const auto& size = parameters.staticData.backendSize;
- if (!parameters.staticData.extrusionTexture || parameters.staticData.extrusionTexture->getSize() != size) {
- parameters.staticData.extrusionTexture = OffscreenTexture(parameters.context, size, OffscreenTextureAttachment::Depth);
- }
-
- parameters.staticData.extrusionTexture->bind();
-
- parameters.context.setStencilMode(gl::StencilMode::disabled());
- parameters.context.setDepthMode(parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite));
- parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, 1.0f, {});
-
- if (evaluated.get<FillExtrusionPattern>().from.empty()) {
- for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
- FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
-
- parameters.programs.fillExtrusion.get(evaluated).draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- FillExtrusionUniforms::values(
- tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
- evaluated.get<FillExtrusionTranslateAnchor>(),
- parameters.state),
- parameters.state,
- parameters.evaluatedLight
- ),
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.triangleSegments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
- getID());
+ if (!renderTexture || renderTexture->getSize() != size) {
+ renderTexture = OffscreenTexture(parameters.context, size, *parameters.staticData.depthRenderbuffer);
}
- } else {
- optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from);
- optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to);
- if (!imagePosA || !imagePosB) {
- return;
+ renderTexture->bind();
+
+ optional<float> depthClearValue = {};
+ if (parameters.staticData.depthRenderbuffer->needsClearing()) depthClearValue = 1.0;
+ // Flag the depth buffer as no longer needing to be cleared for the remainder of this pass.
+ parameters.staticData.depthRenderbuffer->shouldClear(false);
+
+ parameters.context.setStencilMode(gl::StencilMode::disabled());
+ parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {});
+
+ if (evaluated.get<FillExtrusionPattern>().from.empty()) {
+ for (const RenderTile& tile : renderTiles) {
+ assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
+ FillExtrusionBucket& bucket =
+ *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
+
+ parameters.programs.fillExtrusion.get(evaluated).draw(
+ parameters.context, gl::Triangles(),
+ parameters.depthModeFor3D(gl::DepthMode::ReadWrite),
+ gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ FillExtrusionUniforms::values(
+ tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
+ evaluated.get<FillExtrusionTranslateAnchor>(),
+ parameters.state),
+ parameters.state, parameters.evaluatedLight),
+ *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments,
+ bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(),
+ getID());
+ }
+ } else {
+ optional<ImagePosition> imagePosA =
+ parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from);
+ optional<ImagePosition> imagePosB =
+ parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to);
+
+ if (!imagePosA || !imagePosB) {
+ return;
+ }
+
+ parameters.imageManager.bind(parameters.context, 0);
+
+ for (const RenderTile& tile : renderTiles) {
+ assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
+ FillExtrusionBucket& bucket =
+ *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
+
+ parameters.programs.fillExtrusionPattern.get(evaluated).draw(
+ parameters.context, gl::Triangles(),
+ parameters.depthModeFor3D(gl::DepthMode::ReadWrite),
+ gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ FillExtrusionPatternUniforms::values(
+ tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
+ evaluated.get<FillExtrusionTranslateAnchor>(),
+ parameters.state),
+ parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB,
+ evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state,
+ -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
+ parameters.evaluatedLight),
+ *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments,
+ bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(),
+ getID());
+ }
}
- parameters.imageManager.bind(parameters.context, 0);
-
- for (const RenderTile& tile : renderTiles) {
- assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)));
- FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl));
-
- parameters.programs.fillExtrusionPattern.get(evaluated).draw(
- parameters.context,
- gl::Triangles(),
- parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- FillExtrusionPatternUniforms::values(
- tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
- evaluated.get<FillExtrusionTranslateAnchor>(),
- parameters.state),
- parameters.imageManager.getPixelSize(),
- *imagePosA,
- *imagePosB,
- evaluated.get<FillExtrusionPattern>(),
- tile.id,
- parameters.state,
- -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
- parameters.evaluatedLight
- ),
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.triangleSegments,
- bucket.paintPropertyBinders.at(getID()),
- evaluated,
- parameters.state.getZoom(),
- getID());
- }
- }
+ } else if (parameters.pass == RenderPass::Translucent) {
+ parameters.context.bindTexture(renderTexture->getTexture());
- parameters.backend.bind();
- parameters.context.bindTexture(parameters.staticData.extrusionTexture->getTexture());
-
- mat4 viewportMat;
- matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
-
- const Properties<>::PossiblyEvaluated properties;
-
- parameters.programs.extrusionTexture.draw(
- parameters.context,
- gl::Triangles(),
- gl::DepthMode::disabled(),
- gl::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- ExtrusionTextureProgram::UniformValues{
- uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
- uniforms::u_image::Value{ 0 },
- uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() }
- },
- parameters.staticData.extrusionTextureVertexBuffer,
- parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.extrusionTextureSegments,
- ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 },
- properties,
- parameters.state.getZoom(),
- getID());
+ const auto& size = parameters.staticData.backendSize;
+
+ mat4 viewportMat;
+ matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
+
+ const Properties<>::PossiblyEvaluated properties;
+
+ parameters.programs.extrusionTexture.draw(
+ parameters.context, gl::Triangles(), gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(), parameters.colorModeForRenderPass(),
+ ExtrusionTextureProgram::UniformValues{
+ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
+ uniforms::u_image::Value{ 0 },
+ uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } },
+ parameters.staticData.extrusionTextureVertexBuffer,
+ parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.extrusionTextureSegments,
+ ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
+ parameters.state.getZoom(), getID());
+ }
}
bool RenderFillExtrusionLayer::queryIntersectsFeature(
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
index a53e00ca6f..838494cf91 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
@@ -3,6 +3,8 @@
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/offscreen_texture.hpp>
namespace mbgl {
@@ -30,6 +32,8 @@ public:
style::FillExtrusionPaintProperties::PossiblyEvaluated evaluated;
const style::FillExtrusionLayer::Impl& impl() const;
+
+ optional<OffscreenTexture> renderTexture;
};
template <>
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp
index 2a61a9e993..22cb9563c1 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.cpp
@@ -64,15 +64,15 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)));
FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl));
- auto draw = [&] (uint8_t sublayer,
- auto& program,
+ auto draw = [&] (auto& program,
const auto& drawMode,
+ const auto& depthMode,
const auto& indexBuffer,
const auto& segments) {
program.get(evaluated).draw(
parameters.context,
drawMode,
- parameters.depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
+ depthMode,
parameters.stencilModeForClipping(tile.clip),
parameters.colorModeForRenderPass(),
FillProgram::UniformValues {
@@ -93,29 +93,25 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
);
};
- if (evaluated.get<FillAntialias>() && !unevaluated.get<FillOutlineColor>().isUndefined() && parameters.pass == RenderPass::Translucent) {
- draw(2,
- parameters.programs.fillOutline,
- gl::Lines { 2.0f },
- *bucket.lineIndexBuffer,
- bucket.lineSegments);
- }
-
// Only draw the fill when it's opaque and we're drawing opaque fragments,
// or when it's translucent and we're drawing translucent fragments.
if ((evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f
&& evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) {
- draw(1,
- parameters.programs.fill,
+ draw(parameters.programs.fill,
gl::Triangles(),
+ parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque
+ ? gl::DepthMode::ReadWrite
+ : gl::DepthMode::ReadOnly),
*bucket.triangleIndexBuffer,
bucket.triangleSegments);
}
- if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined() && parameters.pass == RenderPass::Translucent) {
- draw(2,
- parameters.programs.fillOutline,
- gl::Lines { 2.0f },
+ if (evaluated.get<FillAntialias>() && parameters.pass == RenderPass::Translucent) {
+ draw(parameters.programs.fillOutline,
+ gl::Lines{ 2.0f },
+ parameters.depthModeForSublayer(
+ unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0,
+ gl::DepthMode::ReadOnly),
*bucket.lineIndexBuffer,
bucket.lineSegments);
}
@@ -138,15 +134,15 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
assert(dynamic_cast<FillBucket*>(tile.tile.getBucket(*baseImpl)));
FillBucket& bucket = *reinterpret_cast<FillBucket*>(tile.tile.getBucket(*baseImpl));
- auto draw = [&] (uint8_t sublayer,
- auto& program,
+ auto draw = [&] (auto& program,
const auto& drawMode,
+ const auto& depthMode,
const auto& indexBuffer,
const auto& segments) {
program.get(evaluated).draw(
parameters.context,
drawMode,
- parameters.depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
+ depthMode,
parameters.stencilModeForClipping(tile.clip),
parameters.colorModeForRenderPass(),
FillPatternUniforms::values(
@@ -171,21 +167,19 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) {
);
};
- draw(0,
- parameters.programs.fillPattern,
+ draw(parameters.programs.fillPattern,
gl::Triangles(),
+ parameters.depthModeForSublayer(1, gl::DepthMode::ReadWrite),
*bucket.triangleIndexBuffer,
bucket.triangleSegments);
- if (!evaluated.get<FillAntialias>() || !unevaluated.get<FillOutlineColor>().isUndefined()) {
- continue;
+ if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined()) {
+ draw(parameters.programs.fillOutlinePattern,
+ gl::Lines { 2.0f },
+ parameters.depthModeForSublayer(2, gl::DepthMode::ReadOnly),
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments);
}
-
- draw(2,
- parameters.programs.fillOutlinePattern,
- gl::Lines { 2.0f },
- *bucket.lineIndexBuffer,
- bucket.lineSegments);
}
}
}
diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp
index ebdaecd3a3..299db844bc 100644
--- a/src/mbgl/renderer/paint_parameters.cpp
+++ b/src/mbgl/renderer/paint_parameters.cpp
@@ -1,6 +1,5 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/update_parameters.hpp>
-#include <mbgl/renderer/render_style.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/map/transform_state.hpp>
@@ -11,17 +10,19 @@ PaintParameters::PaintParameters(gl::Context& context_,
GLContextMode contextMode_,
RendererBackend& backend_,
const UpdateParameters& updateParameters,
- RenderStyle& style,
+ const EvaluatedLight& evaluatedLight_,
RenderStaticData& staticData_,
- FrameHistory& frameHistory_)
+ FrameHistory& frameHistory_,
+ ImageManager& imageManager_,
+ LineAtlas& lineAtlas_)
: context(context_),
backend(backend_),
state(updateParameters.transformState),
- evaluatedLight(style.getRenderLight().getEvaluated()),
+ evaluatedLight(evaluatedLight_),
staticData(staticData_),
frameHistory(frameHistory_),
- imageManager(*style.imageManager),
- lineAtlas(*style.lineAtlas),
+ imageManager(imageManager_),
+ lineAtlas(lineAtlas_),
mapMode(updateParameters.mode),
debugOptions(updateParameters.debugOptions),
contextMode(contextMode_),
@@ -61,6 +62,10 @@ gl::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gl::DepthMode::Ma
return gl::DepthMode { gl::DepthMode::LessEqual, mask, { nearDepth, farDepth } };
}
+gl::DepthMode PaintParameters::depthModeFor3D(gl::DepthMode::Mask mask) const {
+ return gl::DepthMode { gl::DepthMode::LessEqual, mask, { 0.0, 1.0 } };
+}
+
gl::StencilMode PaintParameters::stencilModeForClipping(const ClipID& id) const {
return gl::StencilMode {
gl::StencilMode::Equal { static_cast<uint32_t>(id.mask.to_ulong()) },
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index e9d3562a75..4a2c2c6f12 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -15,7 +15,6 @@ namespace mbgl {
class RendererBackend;
class UpdateParameters;
-class RenderStyle;
class RenderStaticData;
class FrameHistory;
class Programs;
@@ -31,9 +30,11 @@ public:
GLContextMode,
RendererBackend&,
const UpdateParameters&,
- RenderStyle&,
+ const EvaluatedLight&,
RenderStaticData&,
- FrameHistory&);
+ FrameHistory&,
+ ImageManager&,
+ LineAtlas&);
gl::Context& context;
RendererBackend& backend;
@@ -59,6 +60,7 @@ public:
Programs& programs;
gl::DepthMode depthModeForSublayer(uint8_t n, gl::DepthMode::Mask) const;
+ gl::DepthMode depthModeFor3D(gl::DepthMode::Mask) const;
gl::StencilMode stencilModeForClipping(const ClipID&) const;
gl::ColorMode colorModeForRenderPass() const;
diff --git a/src/mbgl/renderer/render_item.hpp b/src/mbgl/renderer/render_item.hpp
deleted file mode 100644
index 4bf5629263..0000000000
--- a/src/mbgl/renderer/render_item.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <mbgl/util/color.hpp>
-
-#include <unordered_set>
-#include <vector>
-
-namespace mbgl {
-
-class RenderLayer;
-class RenderSource;
-class RenderTile;
-class Bucket;
-
-namespace style {
-} // namespace style
-
-class RenderItem {
-public:
- RenderItem(RenderLayer& layer_,
- RenderSource* renderSource_)
- : layer(layer_), source(renderSource_) {
- }
-
- RenderLayer& layer;
- RenderSource* source;
-};
-
-class RenderData {
-public:
- Color backgroundColor;
- std::unordered_set<RenderSource*> sources;
- std::vector<RenderItem> order;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/renderer/render_pass.hpp b/src/mbgl/renderer/render_pass.hpp
index ae2b923ba1..5d18304129 100644
--- a/src/mbgl/renderer/render_pass.hpp
+++ b/src/mbgl/renderer/render_pass.hpp
@@ -11,6 +11,7 @@ enum class RenderPass : uint8_t {
None = 0,
Opaque = 1 << 0,
Translucent = 1 << 1,
+ Pass3D = 1 << 2,
};
MBGL_CONSTEXPR RenderPass operator|(RenderPass a, RenderPass b) {
diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp
index b565439588..8293923ff6 100644
--- a/src/mbgl/renderer/render_source.hpp
+++ b/src/mbgl/renderer/render_source.hpp
@@ -18,7 +18,6 @@ namespace mbgl {
class PaintParameters;
class TransformState;
class RenderTile;
-class RenderStyle;
class RenderLayer;
class RenderedQueryOptions;
class SourceQueryOptions;
@@ -63,7 +62,7 @@ public:
virtual std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const = 0;
virtual std::vector<Feature>
diff --git a/src/mbgl/renderer/render_static_data.cpp b/src/mbgl/renderer/render_static_data.cpp
index 4c6028d7b6..ccf239e643 100644
--- a/src/mbgl/renderer/render_static_data.cpp
+++ b/src/mbgl/renderer/render_static_data.cpp
@@ -32,9 +32,9 @@ static gl::IndexVector<gl::LineStrip> tileLineStripIndices() {
static gl::VertexVector<RasterLayoutVertex> rasterVertices() {
gl::VertexVector<RasterLayoutVertex> result;
result.emplace_back(RasterProgram::layoutVertex({ 0, 0 }, { 0, 0 }));
- result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, 0 }, { 32767, 0 }));
- result.emplace_back(RasterProgram::layoutVertex({ 0, util::EXTENT }, { 0, 32767 }));
- result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }));
+ result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, 0 }, { util::EXTENT, 0 }));
+ result.emplace_back(RasterProgram::layoutVertex({ 0, util::EXTENT }, { 0, util::EXTENT }));
+ result.emplace_back(RasterProgram::layoutVertex({ util::EXTENT, util::EXTENT }, { util::EXTENT, util::EXTENT }));
return result;
}
diff --git a/src/mbgl/renderer/render_static_data.hpp b/src/mbgl/renderer/render_static_data.hpp
index 07a47b4c8f..cf58c31f4d 100644
--- a/src/mbgl/renderer/render_static_data.hpp
+++ b/src/mbgl/renderer/render_static_data.hpp
@@ -4,7 +4,6 @@
#include <mbgl/gl/index_buffer.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/util/optional.hpp>
-#include <mbgl/util/offscreen_texture.hpp>
#include <string>
@@ -26,7 +25,9 @@ public:
SegmentVector<RasterAttributes> rasterSegments;
SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments;
- optional<OffscreenTexture> extrusionTexture;
+ optional<gl::Renderbuffer<gl::RenderbufferType::DepthComponent>> depthRenderbuffer;
+ bool has3D = false;
+ Size backendSize;
Programs programs;
diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp
deleted file mode 100644
index 3d95b12bc4..0000000000
--- a/src/mbgl/renderer/render_style.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-#include <mbgl/renderer/render_style.hpp>
-#include <mbgl/renderer/render_style_observer.hpp>
-#include <mbgl/renderer/update_parameters.hpp>
-#include <mbgl/renderer/transition_parameters.hpp>
-#include <mbgl/renderer/property_evaluation_parameters.hpp>
-#include <mbgl/renderer/tile_parameters.hpp>
-#include <mbgl/renderer/render_source.hpp>
-#include <mbgl/renderer/render_item.hpp>
-#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/renderer/layers/render_background_layer.hpp>
-#include <mbgl/renderer/layers/render_circle_layer.hpp>
-#include <mbgl/renderer/layers/render_custom_layer.hpp>
-#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
-#include <mbgl/renderer/layers/render_fill_layer.hpp>
-#include <mbgl/renderer/layers/render_line_layer.hpp>
-#include <mbgl/renderer/layers/render_raster_layer.hpp>
-#include <mbgl/renderer/layers/render_symbol_layer.hpp>
-#include <mbgl/renderer/backend_scope.hpp>
-#include <mbgl/renderer/style_diff.hpp>
-#include <mbgl/renderer/image_manager.hpp>
-#include <mbgl/renderer/query.hpp>
-#include <mbgl/style/style.hpp>
-#include <mbgl/style/source_impl.hpp>
-#include <mbgl/style/transition_options.hpp>
-#include <mbgl/sprite/sprite_loader.hpp>
-#include <mbgl/text/glyph_manager.hpp>
-#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/tile/tile.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/string.hpp>
-#include <mbgl/util/logging.hpp>
-
-namespace mbgl {
-
-using namespace style;
-
-RenderStyleObserver nullObserver;
-
-RenderStyle::RenderStyle(Scheduler& scheduler_, FileSource& fileSource_)
- : scheduler(scheduler_),
- fileSource(fileSource_),
- glyphManager(std::make_unique<GlyphManager>(fileSource)),
- imageManager(std::make_unique<ImageManager>()),
- lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
- imageImpls(makeMutable<std::vector<Immutable<style::Image::Impl>>>()),
- sourceImpls(makeMutable<std::vector<Immutable<style::Source::Impl>>>()),
- layerImpls(makeMutable<std::vector<Immutable<style::Layer::Impl>>>()),
- renderLight(makeMutable<Light::Impl>()),
- observer(&nullObserver) {
- glyphManager->setObserver(this);
-}
-
-RenderStyle::~RenderStyle() {
- assert(BackendScope::exists()); // Required for custom layers.
-}
-
-void RenderStyle::setObserver(RenderStyleObserver* observer_) {
- observer = observer_;
-}
-
-std::vector<const RenderLayer*> RenderStyle::getRenderLayers() const {
- std::vector<const RenderLayer*> result;
- result.reserve(renderLayers.size());
- for (const auto& layer : *layerImpls) {
- result.push_back(getRenderLayer(layer->id));
- }
- return result;
-}
-
-RenderLayer* RenderStyle::getRenderLayer(const std::string& id) {
- auto it = renderLayers.find(id);
- return it != renderLayers.end() ? it->second.get() : nullptr;
-}
-
-const RenderLayer* RenderStyle::getRenderLayer(const std::string& id) const {
- auto it = renderLayers.find(id);
- return it != renderLayers.end() ? it->second.get() : nullptr;
-}
-
-const RenderLight& RenderStyle::getRenderLight() const {
- return renderLight;
-}
-
-void RenderStyle::update(const UpdateParameters& parameters) {
- assert(BackendScope::exists()); // Required for custom layers.
-
- const bool zoomChanged = zoomHistory.update(parameters.transformState.getZoom(), parameters.timePoint);
-
- const TransitionParameters transitionParameters {
- parameters.timePoint,
- parameters.mode == MapMode::Continuous ? parameters.transitionOptions : TransitionOptions()
- };
-
- const PropertyEvaluationParameters evaluationParameters {
- zoomHistory,
- parameters.timePoint,
- parameters.mode == MapMode::Continuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero()
- };
-
- const TileParameters tileParameters {
- parameters.pixelRatio,
- parameters.debugOptions,
- parameters.transformState,
- parameters.scheduler,
- parameters.fileSource,
- parameters.mode,
- parameters.annotationManager,
- *imageManager,
- *glyphManager,
- parameters.prefetchZoomDelta
- };
-
- glyphManager->setURL(parameters.glyphURL);
-
- // Update light.
- const bool lightChanged = renderLight.impl != parameters.light;
-
- if (lightChanged) {
- renderLight.impl = parameters.light;
- renderLight.transition(transitionParameters);
- }
-
- if (lightChanged || zoomChanged || renderLight.hasTransition()) {
- renderLight.evaluate(evaluationParameters);
- }
-
-
- const ImageDifference imageDiff = diffImages(imageImpls, parameters.images);
- imageImpls = parameters.images;
-
- // Remove removed images from sprite atlas.
- for (const auto& entry : imageDiff.removed) {
- imageManager->removeImage(entry.first);
- }
-
- // Add added images to sprite atlas.
- for (const auto& entry : imageDiff.added) {
- imageManager->addImage(entry.second);
- }
-
- // Update changed images.
- for (const auto& entry : imageDiff.changed) {
- imageManager->updateImage(entry.second.after);
- }
-
- imageManager->setLoaded(parameters.spriteLoaded);
-
-
- const LayerDifference layerDiff = diffLayers(layerImpls, parameters.layers);
- layerImpls = parameters.layers;
-
- // Remove render layers for removed layers.
- for (const auto& entry : layerDiff.removed) {
- renderLayers.erase(entry.first);
- }
-
- // Create render layers for newly added layers.
- for (const auto& entry : layerDiff.added) {
- renderLayers.emplace(entry.first, RenderLayer::create(entry.second));
- }
-
- // Update render layers for changed layers.
- for (const auto& entry : layerDiff.changed) {
- renderLayers.at(entry.first)->setImpl(entry.second.after);
- }
-
- // Update layers for class and zoom changes.
- for (const auto& entry : renderLayers) {
- RenderLayer& layer = *entry.second;
- const bool layerAdded = layerDiff.added.count(entry.first);
- const bool layerChanged = layerDiff.changed.count(entry.first);
-
- if (layerAdded || layerChanged) {
- layer.transition(transitionParameters);
- }
-
- if (layerAdded || layerChanged || zoomChanged || layer.hasTransition()) {
- layer.evaluate(evaluationParameters);
- }
- }
-
-
- const SourceDifference sourceDiff = diffSources(sourceImpls, parameters.sources);
- sourceImpls = parameters.sources;
-
- // Remove render layers for removed sources.
- for (const auto& entry : sourceDiff.removed) {
- renderSources.erase(entry.first);
- }
-
- // Create render sources for newly added sources.
- for (const auto& entry : sourceDiff.added) {
- std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second);
- renderSource->setObserver(this);
- renderSources.emplace(entry.first, std::move(renderSource));
- }
-
- // Update all sources.
- for (const auto& source : *sourceImpls) {
- std::vector<Immutable<Layer::Impl>> filteredLayers;
- bool needsRendering = false;
- bool needsRelayout = false;
-
- for (const auto& layer : *layerImpls) {
- if (layer->type == LayerType::Background ||
- layer->type == LayerType::Custom ||
- layer->source != source->id) {
- continue;
- }
-
- if (!needsRendering && getRenderLayer(layer->id)->needsRendering(zoomHistory.lastZoom)) {
- needsRendering = true;
- }
-
- if (!needsRelayout && (
- hasLayoutDifference(layerDiff, layer->id) ||
- !imageDiff.added.empty() ||
- !imageDiff.removed.empty() ||
- !imageDiff.changed.empty())) {
- needsRelayout = true;
- }
-
- filteredLayers.push_back(layer);
- }
-
- renderSources.at(source->id)->update(source,
- filteredLayers,
- needsRendering,
- needsRelayout,
- tileParameters);
- }
-}
-
-RenderSource* RenderStyle::getRenderSource(const std::string& id) const {
- auto it = renderSources.find(id);
- return it != renderSources.end() ? it->second.get() : nullptr;
-}
-
-bool RenderStyle::hasTransitions() const {
- if (renderLight.hasTransition()) {
- return true;
- }
-
- for (const auto& entry : renderLayers) {
- if (entry.second->hasTransition()) {
- return true;
- }
- }
-
- return false;
-}
-
-bool RenderStyle::isLoaded() const {
- for (const auto& entry: renderSources) {
- if (!entry.second->isLoaded()) {
- return false;
- }
- }
-
- if (!imageManager->isLoaded()) {
- return false;
- }
-
- return true;
-}
-
-RenderData RenderStyle::getRenderData(MapDebugOptions debugOptions, float angle) {
- RenderData result;
-
- for (const auto& entry : renderSources) {
- if (entry.second->isEnabled()) {
- result.sources.insert(entry.second.get());
- }
- }
-
- for (auto& layerImpl : *layerImpls) {
- RenderLayer* layer = getRenderLayer(layerImpl->id);
- assert(layer);
-
- if (!layer->needsRendering(zoomHistory.lastZoom)) {
- continue;
- }
-
- if (const RenderBackgroundLayer* background = layer->as<RenderBackgroundLayer>()) {
- if (debugOptions & MapDebugOptions::Overdraw) {
- // We want to skip glClear optimization in overdraw mode.
- result.order.emplace_back(*layer, nullptr);
- continue;
- }
- const BackgroundPaintProperties::PossiblyEvaluated& paint = background->evaluated;
- if (layerImpl.get() == layerImpls->at(0).get() && paint.get<BackgroundPattern>().from.empty()) {
- // This is a solid background. We can use glClear().
- result.backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>();
- } else {
- // This is a textured background, or not the bottommost layer. We need to render it with a quad.
- result.order.emplace_back(*layer, nullptr);
- }
- continue;
- }
-
- if (layer->is<RenderCustomLayer>()) {
- result.order.emplace_back(*layer, nullptr);
- continue;
- }
-
- RenderSource* source = getRenderSource(layer->baseImpl->source);
- if (!source) {
- Log::Warning(Event::Render, "can't find source for layer '%s'", layer->getID().c_str());
- continue;
- }
-
- const bool symbolLayer = layer->is<RenderSymbolLayer>();
-
- auto sortedTiles = source->getRenderTiles();
- if (symbolLayer) {
- // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn
- // on top of each other, with lower symbols being drawn on top of higher symbols.
- std::sort(sortedTiles.begin(), sortedTiles.end(),
- [angle](const RenderTile& a, const RenderTile& b) {
- Point<float> pa(a.id.canonical.x, a.id.canonical.y);
- Point<float> pb(b.id.canonical.x, b.id.canonical.y);
-
- auto par = util::rotate(pa, angle);
- auto pbr = util::rotate(pb, angle);
-
- return std::tie(par.y, par.x) < std::tie(pbr.y, pbr.x);
- });
- } else {
- std::sort(sortedTiles.begin(), sortedTiles.end(),
- [](const auto& a, const auto& b) { return a.get().id < b.get().id; });
- }
-
- std::vector<std::reference_wrapper<RenderTile>> sortedTilesForInsertion;
- for (auto& sortedTile : sortedTiles) {
- auto& tile = sortedTile.get();
- if (!tile.tile.isRenderable()) {
- continue;
- }
-
- // We're not clipping symbol layers, so when we have both parents and children of symbol
- // layers, we drop all children in favor of their parent to avoid duplicate labels.
- // See https://github.com/mapbox/mapbox-gl-native/issues/2482
- if (symbolLayer) {
- bool skip = false;
- // Look back through the buckets we decided to render to find out whether there is
- // already a bucket from this layer that is a parent of this tile. Tiles are ordered
- // by zoom level when we obtain them from getTiles().
- for (auto it = sortedTilesForInsertion.rbegin();
- it != sortedTilesForInsertion.rend(); ++it) {
- if (tile.tile.id.isChildOf(it->get().tile.id)) {
- skip = true;
- break;
- }
- }
- if (skip) {
- continue;
- }
- }
-
- auto bucket = tile.tile.getBucket(*layer->baseImpl);
- if (bucket) {
- sortedTilesForInsertion.emplace_back(tile);
- tile.used = true;
- }
- }
- layer->setRenderTiles(std::move(sortedTilesForInsertion));
- result.order.emplace_back(*layer, source);
- }
-
- return result;
-}
-
-std::vector<Feature> RenderStyle::queryRenderedFeatures(const ScreenLineString& geometry,
- const TransformState& transformState,
- const RenderedQueryOptions& options) const {
- std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
-
- if (options.layerIDs) {
- std::unordered_set<std::string> sourceIDs;
- for (const auto& layerID : *options.layerIDs) {
- if (const RenderLayer* layer = getRenderLayer(layerID)) {
- sourceIDs.emplace(layer->baseImpl->source);
- }
- }
- for (const auto& sourceID : sourceIDs) {
- if (RenderSource* renderSource = getRenderSource(sourceID)) {
- auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, *this, options);
- std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
- }
- }
- } else {
- for (const auto& entry : renderSources) {
- auto sourceResults = entry.second->queryRenderedFeatures(geometry, transformState, *this, options);
- std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
- }
- }
-
- std::vector<Feature> result;
-
- if (resultsByLayer.empty()) {
- return result;
- }
-
- // Combine all results based on the style layer order.
- for (const auto& layerImpl : *layerImpls) {
- const RenderLayer* layer = getRenderLayer(layerImpl->id);
- if (!layer->needsRendering(zoomHistory.lastZoom)) {
- continue;
- }
- auto it = resultsByLayer.find(layer->baseImpl->id);
- if (it != resultsByLayer.end()) {
- std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
- }
- }
-
- return result;
-}
-
-void RenderStyle::onLowMemory() {
- for (const auto& entry : renderSources) {
- entry.second->onLowMemory();
- }
-}
-
-void RenderStyle::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
- Log::Error(Event::Style, "Failed to load glyph range %d-%d for font stack %s: %s",
- glyphRange.first, glyphRange.second, fontStackToString(fontStack).c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
-}
-
-void RenderStyle::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
- Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
- util::toString(tileID).c_str(), source.baseImpl->id.c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
-}
-
-void RenderStyle::onTileChanged(RenderSource&, const OverscaledTileID&) {
- observer->onInvalidate();
-}
-
-void RenderStyle::dumpDebugLogs() const {
- for (const auto& entry : renderSources) {
- entry.second->dumpDebugLogs();
- }
-
- imageManager->dumpDebugLogs();
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/renderer/render_style.hpp b/src/mbgl/renderer/render_style.hpp
deleted file mode 100644
index 23a640c482..0000000000
--- a/src/mbgl/renderer/render_style.hpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#pragma once
-
-#include <mbgl/style/image.hpp>
-#include <mbgl/renderer/render_source.hpp>
-#include <mbgl/renderer/render_source_observer.hpp>
-#include <mbgl/renderer/render_layer.hpp>
-#include <mbgl/renderer/render_light.hpp>
-#include <mbgl/text/glyph_manager_observer.hpp>
-#include <mbgl/map/zoom_history.hpp>
-#include <mbgl/map/mode.hpp>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace mbgl {
-
-class FileSource;
-class GlyphManager;
-class ImageManager;
-class LineAtlas;
-class RenderData;
-class TransformState;
-class RenderedQueryOptions;
-class Scheduler;
-class UpdateParameters;
-class RenderStyleObserver;
-
-namespace style {
-class Image;
-class Source;
-class Layer;
-} // namespace style
-
-class RenderStyle : public GlyphManagerObserver,
- public RenderSourceObserver {
-public:
- RenderStyle(Scheduler&, FileSource&);
- ~RenderStyle() final;
-
- void setObserver(RenderStyleObserver*);
- void update(const UpdateParameters&);
-
- bool isLoaded() const;
- bool hasTransitions() const;
-
- RenderSource* getRenderSource(const std::string& id) const;
-
- std::vector<const RenderLayer*> getRenderLayers() const;
-
- RenderLayer* getRenderLayer(const std::string& id);
- const RenderLayer* getRenderLayer(const std::string& id) const;
-
- const RenderLight& getRenderLight() const;
-
- RenderData getRenderData(MapDebugOptions, float angle);
-
- std::vector<Feature> queryRenderedFeatures(const ScreenLineString& geometry,
- const TransformState& transformState,
- const RenderedQueryOptions& options) const;
-
- void onLowMemory();
-
- void dumpDebugLogs() const;
-
- Scheduler& scheduler;
- FileSource& fileSource;
- std::unique_ptr<GlyphManager> glyphManager;
- std::unique_ptr<ImageManager> imageManager;
- std::unique_ptr<LineAtlas> lineAtlas;
-
-private:
- Immutable<std::vector<Immutable<style::Image::Impl>>> imageImpls;
- Immutable<std::vector<Immutable<style::Source::Impl>>> sourceImpls;
- Immutable<std::vector<Immutable<style::Layer::Impl>>> layerImpls;
-
- std::unordered_map<std::string, std::unique_ptr<RenderSource>> renderSources;
- std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
- RenderLight renderLight;
-
- // GlyphManagerObserver implementation.
- void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
-
- // RenderSourceObserver implementation.
- void onTileChanged(RenderSource&, const OverscaledTileID&) override;
- void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
-
- RenderStyleObserver* observer;
- ZoomHistory zoomHistory;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/renderer/render_style_observer.hpp b/src/mbgl/renderer/render_style_observer.hpp
deleted file mode 100644
index 5852dd68b8..0000000000
--- a/src/mbgl/renderer/render_style_observer.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <exception>
-
-namespace mbgl {
-
-class RenderStyleObserver {
-public:
- virtual ~RenderStyleObserver() = default;
- virtual void onInvalidate() {}
- virtual void onResourceError(std::exception_ptr) {}
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index c9912f0563..8df31f8d7c 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -74,57 +74,75 @@ void RenderTile::finishRender(PaintParameters& parameters) {
static const style::Properties<>::PossiblyEvaluated properties {};
static const DebugProgram::PaintPropertyBinders paintAttibuteData(properties, 0);
- auto draw = [&] (Color color, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments, auto drawMode) {
+ if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
+ if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
+ tile.debugBucket->complete != tile.isComplete() ||
+ !(tile.debugBucket->modified == tile.modified) ||
+ !(tile.debugBucket->expires == tile.expires) ||
+ tile.debugBucket->debugMode != parameters.debugOptions) {
+ tile.debugBucket = std::make_unique<DebugBucket>(
+ tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
+ tile.expires, parameters.debugOptions, parameters.context);
+ }
+
parameters.programs.debug.draw(
parameters.context,
- drawMode,
+ gl::Lines { 4.0f * parameters.pixelRatio },
gl::DepthMode::disabled(),
parameters.stencilModeForClipping(clip),
gl::ColorMode::unblended(),
DebugProgram::UniformValues {
uniforms::u_matrix::Value{ matrix },
- uniforms::u_color::Value{ color }
+ uniforms::u_color::Value{ Color::white() }
},
- vertexBuffer,
- indexBuffer,
- segments,
+ *tile.debugBucket->vertexBuffer,
+ *tile.debugBucket->indexBuffer,
+ tile.debugBucket->segments,
paintAttibuteData,
properties,
parameters.state.getZoom(),
"debug"
);
- };
-
- if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
- if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
- tile.debugBucket->complete != tile.isComplete() ||
- !(tile.debugBucket->modified == tile.modified) ||
- !(tile.debugBucket->expires == tile.expires) ||
- tile.debugBucket->debugMode != parameters.debugOptions) {
- tile.debugBucket = std::make_unique<DebugBucket>(
- tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
- tile.expires, parameters.debugOptions, parameters.context);
- }
- draw(Color::white(),
- *tile.debugBucket->vertexBuffer,
- *tile.debugBucket->indexBuffer,
- tile.debugBucket->segments,
- gl::Lines { 4.0f * parameters.pixelRatio });
-
- draw(Color::black(),
- *tile.debugBucket->vertexBuffer,
- *tile.debugBucket->indexBuffer,
- tile.debugBucket->segments,
- gl::Lines { 2.0f * parameters.pixelRatio });
+ parameters.programs.debug.draw(
+ parameters.context,
+ gl::Lines { 2.0f * parameters.pixelRatio },
+ gl::DepthMode::disabled(),
+ parameters.stencilModeForClipping(clip),
+ gl::ColorMode::unblended(),
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::black() }
+ },
+ *tile.debugBucket->vertexBuffer,
+ *tile.debugBucket->indexBuffer,
+ tile.debugBucket->segments,
+ paintAttibuteData,
+ properties,
+ parameters.state.getZoom(),
+ "debug"
+ );
}
if (parameters.debugOptions & MapDebugOptions::TileBorders) {
- draw(Color::red(),
- parameters.staticData.tileVertexBuffer,
- parameters.staticData.tileBorderIndexBuffer,
- parameters.staticData.tileBorderSegments,
- gl::LineStrip { 4.0f * parameters.pixelRatio });
+ parameters.programs.debug.draw(
+ parameters.context,
+ gl::LineStrip { 4.0f * parameters.pixelRatio },
+ gl::DepthMode::disabled(),
+ parameters.stencilModeForClipping(clip),
+ gl::ColorMode::unblended(),
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::red() }
+ },
+ parameters.staticData.tileVertexBuffer,
+ parameters.staticData.tileBorderIndexBuffer,
+ parameters.staticData.tileBorderSegments,
+ paintAttibuteData,
+ properties,
+ parameters.state.getZoom(),
+ "debug"
+ );
}
}
diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp
index 9f4b897d6e..e915f5e146 100644
--- a/src/mbgl/renderer/renderer.cpp
+++ b/src/mbgl/renderer/renderer.cpp
@@ -1,6 +1,6 @@
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/renderer/renderer_impl.hpp>
-#include <mbgl/renderer/update_parameters.hpp>
+#include <mbgl/renderer/backend_scope.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
namespace mbgl {
@@ -15,7 +15,14 @@ Renderer::Renderer(RendererBackend& backend,
contextMode_, std::move(programCacheDir_))) {
}
-Renderer::~Renderer() = default;
+Renderer::~Renderer() {
+ BackendScope guard { impl->backend };
+ impl.reset();
+}
+
+void Renderer::markContextLost() {
+ impl->markContextLost();
+}
void Renderer::setObserver(RendererObserver* observer) {
impl->setObserver(observer);
@@ -72,6 +79,7 @@ void Renderer::dumpDebugLogs() {
}
void Renderer::onLowMemory() {
+ BackendScope guard { impl->backend };
impl->onLowMemory();
}
diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp
index dd3c0d41a1..1a828b80a3 100644
--- a/src/mbgl/renderer/renderer_impl.cpp
+++ b/src/mbgl/renderer/renderer_impl.cpp
@@ -1,13 +1,32 @@
+#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/renderer/renderer_impl.hpp>
-#include <mbgl/renderer/render_style.hpp>
+#include <mbgl/renderer/renderer_backend.hpp>
+#include <mbgl/renderer/renderer_observer.hpp>
+#include <mbgl/renderer/render_source.hpp>
+#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/renderer/render_static_data.hpp>
-#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
+#include <mbgl/renderer/transition_parameters.hpp>
+#include <mbgl/renderer/property_evaluation_parameters.hpp>
+#include <mbgl/renderer/tile_parameters.hpp>
+#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/renderer/layers/render_background_layer.hpp>
+#include <mbgl/renderer/layers/render_custom_layer.hpp>
+#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
+#include <mbgl/renderer/style_diff.hpp>
+#include <mbgl/renderer/query.hpp>
#include <mbgl/renderer/backend_scope.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/gl/debugging.hpp>
#include <mbgl/geometry/line_atlas.hpp>
+#include <mbgl/style/source_impl.hpp>
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/text/glyph_manager.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
@@ -24,20 +43,36 @@ Renderer::Impl::Impl(RendererBackend& backend_,
Scheduler& scheduler_,
GLContextMode contextMode_,
const optional<std::string> programCacheDir_)
- : backend(backend_)
- , observer(&nullObserver())
- , contextMode(contextMode_)
- , pixelRatio(pixelRatio_)
- , programCacheDir(programCacheDir_)
- , renderStyle(std::make_unique<RenderStyle>(scheduler_, fileSource_)) {
-
- renderStyle->setObserver(this);
+ : backend(backend_)
+ , scheduler(scheduler_)
+ , fileSource(fileSource_)
+ , observer(&nullObserver())
+ , contextMode(contextMode_)
+ , pixelRatio(pixelRatio_)
+ , programCacheDir(programCacheDir_)
+ , glyphManager(std::make_unique<GlyphManager>(fileSource))
+ , imageManager(std::make_unique<ImageManager>())
+ , lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 }))
+ , imageImpls(makeMutable<std::vector<Immutable<style::Image::Impl>>>())
+ , sourceImpls(makeMutable<std::vector<Immutable<style::Source::Impl>>>())
+ , layerImpls(makeMutable<std::vector<Immutable<style::Layer::Impl>>>())
+ , renderLight(makeMutable<Light::Impl>()) {
+ glyphManager->setObserver(this);
}
Renderer::Impl::~Impl() {
- BackendScope guard { backend };
- renderStyle.reset();
- staticData.reset();
+ assert(BackendScope::exists());
+
+ if (contextLost) {
+ // Signal all RenderCustomLayers that the context was lost
+ // before cleaning up
+ for (const auto& entry : renderLayers) {
+ RenderLayer& layer = *entry.second;
+ if (layer.is<RenderCustomLayer>()) {
+ layer.as<RenderCustomLayer>()->markContextDestroyed();
+ }
+ }
+ }
};
void Renderer::Impl::setObserver(RendererObserver* observer_) {
@@ -45,12 +80,164 @@ void Renderer::Impl::setObserver(RendererObserver* observer_) {
}
void Renderer::Impl::render(const UpdateParameters& updateParameters) {
- // Don't load/render anyting in still mode until explicitly requested.
- if (updateParameters.mode == MapMode::Still && !updateParameters.stillImageRequest) return;
+ if (updateParameters.mode == MapMode::Still) {
+ // Don't load/render anyting in still mode until explicitly requested.
+ if (!updateParameters.stillImageRequest) {
+ return;
+ }
+
+ // Reset zoom history state.
+ zoomHistory.first = true;
+ }
assert(BackendScope::exists());
+
+ updateParameters.annotationManager.updateData();
+
+ const bool zoomChanged = zoomHistory.update(updateParameters.transformState.getZoom(), updateParameters.timePoint);
+
+ const TransitionParameters transitionParameters {
+ updateParameters.timePoint,
+ updateParameters.mode == MapMode::Continuous ? updateParameters.transitionOptions : TransitionOptions()
+ };
+
+ const PropertyEvaluationParameters evaluationParameters {
+ zoomHistory,
+ updateParameters.timePoint,
+ updateParameters.mode == MapMode::Continuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero()
+ };
+
+ const TileParameters tileParameters {
+ updateParameters.pixelRatio,
+ updateParameters.debugOptions,
+ updateParameters.transformState,
+ scheduler,
+ fileSource,
+ updateParameters.mode,
+ updateParameters.annotationManager,
+ *imageManager,
+ *glyphManager,
+ updateParameters.prefetchZoomDelta
+ };
+
+ glyphManager->setURL(updateParameters.glyphURL);
+
+ // Update light.
+ const bool lightChanged = renderLight.impl != updateParameters.light;
+
+ if (lightChanged) {
+ renderLight.impl = updateParameters.light;
+ renderLight.transition(transitionParameters);
+ }
+
+ if (lightChanged || zoomChanged || renderLight.hasTransition()) {
+ renderLight.evaluate(evaluationParameters);
+ }
+
+
+ const ImageDifference imageDiff = diffImages(imageImpls, updateParameters.images);
+ imageImpls = updateParameters.images;
+
+ // Remove removed images from sprite atlas.
+ for (const auto& entry : imageDiff.removed) {
+ imageManager->removeImage(entry.first);
+ }
+
+ // Add added images to sprite atlas.
+ for (const auto& entry : imageDiff.added) {
+ imageManager->addImage(entry.second);
+ }
+
+ // Update changed images.
+ for (const auto& entry : imageDiff.changed) {
+ imageManager->updateImage(entry.second.after);
+ }
+
+ imageManager->setLoaded(updateParameters.spriteLoaded);
+
+
+ const LayerDifference layerDiff = diffLayers(layerImpls, updateParameters.layers);
+ layerImpls = updateParameters.layers;
+
+ // Remove render layers for removed layers.
+ for (const auto& entry : layerDiff.removed) {
+ renderLayers.erase(entry.first);
+ }
+
+ // Create render layers for newly added layers.
+ for (const auto& entry : layerDiff.added) {
+ renderLayers.emplace(entry.first, RenderLayer::create(entry.second));
+ }
+
+ // Update render layers for changed layers.
+ for (const auto& entry : layerDiff.changed) {
+ renderLayers.at(entry.first)->setImpl(entry.second.after);
+ }
+
+ // Update layers for class and zoom changes.
+ for (const auto& entry : renderLayers) {
+ RenderLayer& layer = *entry.second;
+ const bool layerAdded = layerDiff.added.count(entry.first);
+ const bool layerChanged = layerDiff.changed.count(entry.first);
+
+ if (layerAdded || layerChanged) {
+ layer.transition(transitionParameters);
+ }
+
+ if (layerAdded || layerChanged || zoomChanged || layer.hasTransition()) {
+ layer.evaluate(evaluationParameters);
+ }
+ }
+
+
+ const SourceDifference sourceDiff = diffSources(sourceImpls, updateParameters.sources);
+ sourceImpls = updateParameters.sources;
+
+ // Remove render layers for removed sources.
+ for (const auto& entry : sourceDiff.removed) {
+ renderSources.erase(entry.first);
+ }
+
+ // Create render sources for newly added sources.
+ for (const auto& entry : sourceDiff.added) {
+ std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second);
+ renderSource->setObserver(this);
+ renderSources.emplace(entry.first, std::move(renderSource));
+ }
+
+ const bool hasImageDiff = !(imageDiff.added.empty() && imageDiff.removed.empty() && imageDiff.changed.empty());
+
+ // Update all sources.
+ for (const auto& source : *sourceImpls) {
+ std::vector<Immutable<Layer::Impl>> filteredLayers;
+ bool needsRendering = false;
+ bool needsRelayout = false;
+
+ for (const auto& layer : *layerImpls) {
+ if (layer->type == LayerType::Background ||
+ layer->type == LayerType::Custom ||
+ layer->source != source->id) {
+ continue;
+ }
+
+ if (!needsRendering && getRenderLayer(layer->id)->needsRendering(zoomHistory.lastZoom)) {
+ needsRendering = true;
+ }
+
+ if (!needsRelayout && (hasImageDiff || hasLayoutDifference(layerDiff, layer->id))) {
+ needsRelayout = true;
+ }
+
+ filteredLayers.push_back(layer);
+ }
+
+ renderSources.at(source->id)->update(source,
+ filteredLayers,
+ needsRendering,
+ needsRelayout,
+ tileParameters);
+ }
- renderStyle->update(updateParameters);
transformState = updateParameters.transformState;
if (!staticData) {
@@ -63,60 +250,131 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
contextMode,
backend,
updateParameters,
- *renderStyle,
+ renderLight.getEvaluated(),
*staticData,
- frameHistory
+ frameHistory,
+ *imageManager,
+ *lineAtlas
};
- bool loaded = updateParameters.styleLoaded && renderStyle->isLoaded();
+ bool loaded = updateParameters.styleLoaded && isLoaded();
+ if (updateParameters.mode == MapMode::Still && !loaded) {
+ return;
+ }
- if (updateParameters.mode == MapMode::Continuous) {
- if (renderState == RenderState::Never) {
- observer->onWillStartRenderingMap();
- }
+ if (renderState == RenderState::Never) {
+ observer->onWillStartRenderingMap();
+ }
+
+ observer->onWillStartRenderingFrame();
+
+ backend.updateAssumedState();
- observer->onWillStartRenderingFrame();
+ if (parameters.contextMode == GLContextMode::Shared) {
+ parameters.context.setDirtyState();
+ }
- backend.updateAssumedState();
+ Color backgroundColor;
- doRender(parameters);
- parameters.context.performCleanup();
+ class RenderItem {
+ public:
+ RenderLayer& layer;
+ RenderSource* source;
+ };
+
+ std::vector<RenderItem> order;
- observer->onDidFinishRenderingFrame(
- loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial,
- renderStyle->hasTransitions() || frameHistory.needsAnimation(util::DEFAULT_TRANSITION_DURATION)
- );
+ for (auto& layerImpl : *layerImpls) {
+ RenderLayer* layer = getRenderLayer(layerImpl->id);
+ assert(layer);
- if (!loaded) {
- renderState = RenderState::Partial;
- } else if (renderState != RenderState::Fully) {
- renderState = RenderState::Fully;
- observer->onDidFinishRenderingMap();
+ if (!parameters.staticData.has3D && layer->is<RenderFillExtrusionLayer>()) {
+ parameters.staticData.has3D = true;
}
- } else if (loaded) {
- observer->onWillStartRenderingMap();
- observer->onWillStartRenderingFrame();
- backend.updateAssumedState();
+ if (!layer->needsRendering(zoomHistory.lastZoom)) {
+ continue;
+ }
- doRender(parameters);
+ if (const RenderBackgroundLayer* background = layer->as<RenderBackgroundLayer>()) {
+ const BackgroundPaintProperties::PossiblyEvaluated& paint = background->evaluated;
+ if (layerImpl.get() == layerImpls->at(0).get() && paint.get<BackgroundPattern>().from.empty()) {
+ // This is a solid background. We can use glClear().
+ backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>();
+ } else {
+ // This is a textured background, or not the bottommost layer. We need to render it with a quad.
+ order.emplace_back(RenderItem { *layer, nullptr });
+ }
+ continue;
+ }
- observer->onDidFinishRenderingFrame(RendererObserver::RenderMode::Full, false);
- observer->onDidFinishRenderingMap();
+ if (layer->is<RenderCustomLayer>()) {
+ order.emplace_back(RenderItem { *layer, nullptr });
+ continue;
+ }
- // Cleanup only after signaling completion
- parameters.context.performCleanup();
- }
-}
+ RenderSource* source = getRenderSource(layer->baseImpl->source);
+ if (!source) {
+ Log::Warning(Event::Render, "can't find source for layer '%s'", layer->getID().c_str());
+ continue;
+ }
-void Renderer::Impl::doRender(PaintParameters& parameters) {
- if (parameters.contextMode == GLContextMode::Shared) {
- parameters.context.setDirtyState();
- }
+ const bool symbolLayer = layer->is<RenderSymbolLayer>();
+
+ auto sortedTiles = source->getRenderTiles();
+ if (symbolLayer) {
+ // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn
+ // on top of each other, with lower symbols being drawn on top of higher symbols.
+ std::sort(sortedTiles.begin(), sortedTiles.end(), [&](const RenderTile& a, const RenderTile& b) {
+ Point<float> pa(a.id.canonical.x, a.id.canonical.y);
+ Point<float> pb(b.id.canonical.x, b.id.canonical.y);
- RenderData renderData = renderStyle->getRenderData(parameters.debugOptions, parameters.state.getAngle());
- const std::vector<RenderItem>& order = renderData.order;
- const std::unordered_set<RenderSource*>& sources = renderData.sources;
+ auto par = util::rotate(pa, parameters.state.getAngle());
+ auto pbr = util::rotate(pb, parameters.state.getAngle());
+
+ return std::tie(par.y, par.x) < std::tie(pbr.y, pbr.x);
+ });
+ } else {
+ std::sort(sortedTiles.begin(), sortedTiles.end(),
+ [](const auto& a, const auto& b) { return a.get().id < b.get().id; });
+ }
+
+ std::vector<std::reference_wrapper<RenderTile>> sortedTilesForInsertion;
+ for (auto& sortedTile : sortedTiles) {
+ auto& tile = sortedTile.get();
+ if (!tile.tile.isRenderable()) {
+ continue;
+ }
+
+ // We're not clipping symbol layers, so when we have both parents and children of symbol
+ // layers, we drop all children in favor of their parent to avoid duplicate labels.
+ // See https://github.com/mapbox/mapbox-gl-native/issues/2482
+ if (symbolLayer) {
+ bool skip = false;
+ // Look back through the buckets we decided to render to find out whether there is
+ // already a bucket from this layer that is a parent of this tile. Tiles are ordered
+ // by zoom level when we obtain them from getTiles().
+ for (auto it = sortedTilesForInsertion.rbegin();
+ it != sortedTilesForInsertion.rend(); ++it) {
+ if (tile.tile.id.isChildOf(it->get().tile.id)) {
+ skip = true;
+ break;
+ }
+ }
+ if (skip) {
+ continue;
+ }
+ }
+
+ auto bucket = tile.tile.getBucket(*layer->baseImpl);
+ if (bucket) {
+ sortedTilesForInsertion.emplace_back(tile);
+ tile.used = true;
+ }
+ }
+ layer->setRenderTiles(std::move(sortedTilesForInsertion));
+ order.emplace_back(RenderItem { *layer, source });
+ }
frameHistory.record(parameters.timePoint,
parameters.state.getZoom(),
@@ -130,6 +388,39 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
parameters.imageManager.upload(parameters.context, 0);
parameters.lineAtlas.upload(parameters.context, 0);
parameters.frameHistory.upload(parameters.context, 0);
+
+ // Update all clipping IDs + upload buckets.
+ for (const auto& entry : renderSources) {
+ if (entry.second->isEnabled()) {
+ entry.second->startRender(parameters);
+ }
+ }
+ }
+
+ // - 3D PASS -------------------------------------------------------------------------------------
+ // Renders any 3D layers bottom-to-top to unique FBOs with texture attachments, but share the same
+ // depth rbo between them.
+ if (parameters.staticData.has3D) {
+ parameters.staticData.backendSize = parameters.backend.getFramebufferSize();
+
+ MBGL_DEBUG_GROUP(parameters.context, "3d");
+ parameters.pass = RenderPass::Pass3D;
+
+ if (!parameters.staticData.depthRenderbuffer ||
+ parameters.staticData.depthRenderbuffer->size != parameters.staticData.backendSize) {
+ parameters.staticData.depthRenderbuffer =
+ parameters.context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(parameters.staticData.backendSize);
+ }
+ parameters.staticData.depthRenderbuffer->shouldClear(true);
+
+ uint32_t i = static_cast<uint32_t>(order.size()) - 1;
+ for (auto it = order.begin(); it != order.end(); ++it, --i) {
+ parameters.currentLayer = i;
+ if (it->layer.hasRenderPass(parameters.pass)) {
+ MBGL_DEBUG_GROUP(parameters.context, it->layer.getID());
+ it->layer.render(parameters, it->source);
+ }
+ }
}
// - CLEAR -------------------------------------------------------------------------------------
@@ -140,7 +431,7 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
parameters.backend.bind();
parameters.context.clear((parameters.debugOptions & MapDebugOptions::Overdraw)
? Color::black()
- : renderData.backgroundColor,
+ : backgroundColor,
1.0f,
0);
}
@@ -148,13 +439,6 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
// - CLIPPING MASKS ----------------------------------------------------------------------------
// Draws the clipping masks to the stencil buffer.
{
- MBGL_DEBUG_GROUP(parameters.context, "clip");
-
- // Update all clipping IDs.
- for (const auto& source : sources) {
- source->startRender(parameters);
- }
-
MBGL_DEBUG_GROUP(parameters.context, "clipping masks");
static const style::FillPaintProperties::PossiblyEvaluated properties {};
@@ -220,10 +504,7 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
}
#endif
- int indent = 0;
-
// Actually render the layers
- if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; }
parameters.depthRangeSize = 1 - (order.size() + 2) * parameters.numSublayers * parameters.depthEpsilon;
@@ -233,10 +514,6 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
parameters.pass = RenderPass::Opaque;
MBGL_DEBUG_GROUP(parameters.context, "opaque");
- if (debug::renderTree) {
- Log::Info(Event::Render, "%*s%s {", indent++ * 4, "", "opaque");
- }
-
uint32_t i = 0;
for (auto it = order.rbegin(); it != order.rend(); ++it, ++i) {
parameters.currentLayer = i;
@@ -245,10 +522,6 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
it->layer.render(parameters, it->source);
}
}
-
- if (debug::renderTree) {
- Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
- }
}
// - TRANSLUCENT PASS --------------------------------------------------------------------------
@@ -257,10 +530,6 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
parameters.pass = RenderPass::Translucent;
MBGL_DEBUG_GROUP(parameters.context, "translucent");
- if (debug::renderTree) {
- Log::Info(Event::Render, "%*s%s {", indent++ * 4, "", "translucent");
- }
-
uint32_t i = static_cast<uint32_t>(order.size()) - 1;
for (auto it = order.begin(); it != order.end(); ++it, --i) {
parameters.currentLayer = i;
@@ -269,14 +538,8 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
it->layer.render(parameters, it->source);
}
}
-
- if (debug::renderTree) {
- Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
- }
}
- if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; }
-
// - DEBUG PASS --------------------------------------------------------------------------------
// Renders debug overlays.
{
@@ -286,8 +549,10 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
- for (const auto& source : sources) {
- source->finishRender(parameters);
+ for (const auto& entry : renderSources) {
+ if (entry.second->isEnabled()) {
+ entry.second->finishRender(parameters);
+ }
}
}
@@ -319,43 +584,159 @@ void Renderer::Impl::doRender(PaintParameters& parameters) {
{
MBGL_DEBUG_GROUP(parameters.context, "cleanup");
- parameters.context.activeTexture = 1;
+ parameters.context.activeTextureUnit = 1;
parameters.context.texture[1] = 0;
- parameters.context.activeTexture = 0;
+ parameters.context.activeTextureUnit = 0;
parameters.context.texture[0] = 0;
parameters.context.bindVertexArray = 0;
}
+
+ observer->onDidFinishRenderingFrame(
+ loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial,
+ updateParameters.mode == MapMode::Continuous && (hasTransitions() || frameHistory.needsAnimation(util::DEFAULT_TRANSITION_DURATION))
+ );
+
+ if (!loaded) {
+ renderState = RenderState::Partial;
+ } else if (renderState != RenderState::Fully) {
+ renderState = RenderState::Fully;
+ observer->onDidFinishRenderingMap();
+ }
+
+ // Cleanup only after signaling completion
+ parameters.context.performCleanup();
}
std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const {
- return renderStyle->queryRenderedFeatures(geometry, transformState, options);
+ std::vector<const RenderLayer*> layers;
+ if (options.layerIDs) {
+ for (const auto& layerID : *options.layerIDs) {
+ if (const RenderLayer* layer = getRenderLayer(layerID)) {
+ layers.emplace_back(layer);
+ }
+ }
+ } else {
+ for (const auto& entry : renderLayers) {
+ layers.emplace_back(entry.second.get());
+ }
+ }
+
+ std::unordered_set<std::string> sourceIDs;
+ for (const RenderLayer* layer : layers) {
+ sourceIDs.emplace(layer->baseImpl->source);
+ }
+
+ std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
+ for (const auto& sourceID : sourceIDs) {
+ if (RenderSource* renderSource = getRenderSource(sourceID)) {
+ auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options);
+ std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
+ }
+ }
+
+ std::vector<Feature> result;
+
+ if (resultsByLayer.empty()) {
+ return result;
+ }
+
+ // Combine all results based on the style layer order.
+ for (const auto& layerImpl : *layerImpls) {
+ const RenderLayer* layer = getRenderLayer(layerImpl->id);
+ if (!layer->needsRendering(zoomHistory.lastZoom)) {
+ continue;
+ }
+ auto it = resultsByLayer.find(layer->baseImpl->id);
+ if (it != resultsByLayer.end()) {
+ std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
+ }
+ }
+
+ return result;
}
std::vector<Feature> Renderer::Impl::querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options) const {
- const RenderSource* source = renderStyle->getRenderSource(sourceID);
+ const RenderSource* source = getRenderSource(sourceID);
if (!source) return {};
return source->querySourceFeatures(options);
}
-void Renderer::Impl::onInvalidate() {
+void Renderer::Impl::onLowMemory() {
+ assert(BackendScope::exists());
+ backend.getContext().performCleanup();
+ for (const auto& entry : renderSources) {
+ entry.second->onLowMemory();
+ }
observer->onInvalidate();
}
-void Renderer::Impl::onResourceError(std::exception_ptr ptr) {
- observer->onResourceError(ptr);
+void Renderer::Impl::dumDebugLogs() {
+ for (const auto& entry : renderSources) {
+ entry.second->dumpDebugLogs();
+ }
+
+ imageManager->dumpDebugLogs();
}
-void Renderer::Impl::onLowMemory() {
- BackendScope guard { backend };
- backend.getContext().performCleanup();
- renderStyle->onLowMemory();
- observer->onInvalidate();
+RenderLayer* Renderer::Impl::getRenderLayer(const std::string& id) {
+ auto it = renderLayers.find(id);
+ return it != renderLayers.end() ? it->second.get() : nullptr;
}
-void Renderer::Impl::dumDebugLogs() {
- renderStyle->dumpDebugLogs();
+const RenderLayer* Renderer::Impl::getRenderLayer(const std::string& id) const {
+ auto it = renderLayers.find(id);
+ return it != renderLayers.end() ? it->second.get() : nullptr;
+}
+
+RenderSource* Renderer::Impl::getRenderSource(const std::string& id) const {
+ auto it = renderSources.find(id);
+ return it != renderSources.end() ? it->second.get() : nullptr;
+}
+
+bool Renderer::Impl::hasTransitions() const {
+ if (renderLight.hasTransition()) {
+ return true;
+ }
+
+ for (const auto& entry : renderLayers) {
+ if (entry.second->hasTransition()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Renderer::Impl::isLoaded() const {
+ for (const auto& entry: renderSources) {
+ if (!entry.second->isLoaded()) {
+ return false;
+ }
+ }
+
+ if (!imageManager->isLoaded()) {
+ return false;
+ }
+
+ return true;
+}
+
+void Renderer::Impl::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
+ Log::Error(Event::Style, "Failed to load glyph range %d-%d for font stack %s: %s",
+ glyphRange.first, glyphRange.second, fontStackToString(fontStack).c_str(), util::toString(error).c_str());
+ observer->onResourceError(error);
+}
+
+void Renderer::Impl::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
+ Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
+ util::toString(tileID).c_str(), source.baseImpl->id.c_str(), util::toString(error).c_str());
+ observer->onResourceError(error);
+}
+
+void Renderer::Impl::onTileChanged(RenderSource&, const OverscaledTileID&) {
+ observer->onInvalidate();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp
index 079b00d0bb..30e7f70722 100644
--- a/src/mbgl/renderer/renderer_impl.hpp
+++ b/src/mbgl/renderer/renderer_impl.hpp
@@ -1,11 +1,16 @@
#pragma once
#include <mbgl/renderer/renderer.hpp>
-#include <mbgl/renderer/renderer_backend.hpp>
-#include <mbgl/renderer/renderer_observer.hpp>
-#include <mbgl/renderer/render_style_observer.hpp>
+#include <mbgl/renderer/render_source_observer.hpp>
+#include <mbgl/renderer/render_light.hpp>
#include <mbgl/renderer/frame_history.hpp>
+#include <mbgl/style/image.hpp>
+#include <mbgl/style/source.hpp>
+#include <mbgl/style/layer.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/map/zoom_history.hpp>
+#include <mbgl/map/mode.hpp>
+#include <mbgl/text/glyph_manager_observer.hpp>
#include <memory>
#include <string>
@@ -13,17 +18,31 @@
namespace mbgl {
+class RendererBackend;
+class RendererObserver;
+class RenderSource;
+class RenderLayer;
class UpdateParameters;
-class PaintParameters;
-class RenderStyle;
class RenderStaticData;
-
-class Renderer::Impl : public RenderStyleObserver {
+class RenderedQueryOptions;
+class SourceQueryOptions;
+class FileSource;
+class Scheduler;
+class GlyphManager;
+class ImageManager;
+class LineAtlas;
+
+class Renderer::Impl : public GlyphManagerObserver,
+ public RenderSourceObserver{
public:
Impl(RendererBackend&, float pixelRatio_, FileSource&, Scheduler&, GLContextMode,
const optional<std::string> programCacheDir);
~Impl() final;
+ void markContextLost() {
+ contextLost = true;
+ };
+
void setObserver(RendererObserver*);
void render(const UpdateParameters&);
@@ -34,16 +53,28 @@ public:
void onLowMemory();
void dumDebugLogs();
- // RenderStyleObserver implementation
- void onInvalidate() override;
- void onResourceError(std::exception_ptr) override;
-
private:
- void doRender(PaintParameters&);
+ bool isLoaded() const;
+ bool hasTransitions() const;
+
+ RenderSource* getRenderSource(const std::string& id) const;
+
+ RenderLayer* getRenderLayer(const std::string& id);
+ const RenderLayer* getRenderLayer(const std::string& id) const;
+
+ // GlyphManagerObserver implementation.
+ void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
+
+ // RenderSourceObserver implementation.
+ void onTileChanged(RenderSource&, const OverscaledTileID&) override;
+ void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
friend class Renderer;
RendererBackend& backend;
+ Scheduler& scheduler;
+ FileSource& fileSource;
+
RendererObserver* observer;
const GLContextMode contextMode;
@@ -58,10 +89,23 @@ private:
RenderState renderState = RenderState::Never;
FrameHistory frameHistory;
+ ZoomHistory zoomHistory;
TransformState transformState;
- std::unique_ptr<RenderStyle> renderStyle;
+ std::unique_ptr<GlyphManager> glyphManager;
+ std::unique_ptr<ImageManager> imageManager;
+ std::unique_ptr<LineAtlas> lineAtlas;
std::unique_ptr<RenderStaticData> staticData;
+
+ Immutable<std::vector<Immutable<style::Image::Impl>>> imageImpls;
+ Immutable<std::vector<Immutable<style::Source::Impl>>> sourceImpls;
+ Immutable<std::vector<Immutable<style::Layer::Impl>>> layerImpls;
+
+ std::unordered_map<std::string, std::unique_ptr<RenderSource>> renderSources;
+ std::unordered_map<std::string, std::unique_ptr<RenderLayer>> renderLayers;
+ RenderLight renderLight;
+
+ bool contextLost = false;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp
index df8bcc0ae7..504db78ea3 100644
--- a/src/mbgl/renderer/sources/render_geojson_source.cpp
+++ b/src/mbgl/renderer/sources/render_geojson_source.cpp
@@ -2,6 +2,7 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/tile/geojson_tile.hpp>
+#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/algorithm/generate_clip_ids.hpp>
#include <mbgl/algorithm/generate_clip_ids_impl.hpp>
@@ -34,19 +35,26 @@ void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_,
GeoJSONData* data_ = impl().getData();
- if (!data_) {
- return;
- }
-
if (data_ != data) {
data = data_;
tilePyramid.cache.clear();
- for (auto const& item : tilePyramid.tiles) {
- static_cast<GeoJSONTile*>(item.second.get())->updateData(data->getTile(item.first.canonical));
+ if (data) {
+ const uint8_t maxZ = impl().getZoomRange().max;
+ for (const auto& pair : tilePyramid.tiles) {
+ if (pair.first.canonical.z <= maxZ) {
+ static_cast<GeoJSONTile*>(pair.second.get())->updateData(data->getTile(pair.first.canonical));
+ }
+ }
}
}
+ if (!data) {
+ tilePyramid.tiles.clear();
+ tilePyramid.renderTiles.clear();
+ return;
+ }
+
tilePyramid.update(layers,
needsRendering,
needsRelayout,
@@ -75,9 +83,9 @@ std::vector<std::reference_wrapper<RenderTile>> RenderGeoJSONSource::getRenderTi
std::unordered_map<std::string, std::vector<Feature>>
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {
- return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options);
+ return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
}
std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const {
diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp
index b84156ab95..72ab4879ef 100644
--- a/src/mbgl/renderer/sources/render_geojson_source.hpp
+++ b/src/mbgl/renderer/sources/render_geojson_source.hpp
@@ -30,7 +30,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final;
std::vector<Feature>
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp
index 11ff8c26b1..9140e01711 100644
--- a/src/mbgl/renderer/sources/render_image_source.cpp
+++ b/src/mbgl/renderer/sources/render_image_source.cpp
@@ -10,6 +10,7 @@
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/util/constants.hpp>
namespace mbgl {
@@ -82,7 +83,7 @@ void RenderImageSource::finishRender(PaintParameters& parameters) {
std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const RenderStyle&,
+ const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) const {
return std::unordered_map<std::string, std::vector<Feature>> {};
}
@@ -193,11 +194,11 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
bucket->vertices.emplace_back(
RasterProgram::layoutVertex({ geomCoords[0].x, geomCoords[0].y }, { 0, 0 }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[1].x, geomCoords[1].y }, { 32767, 0 }));
+ RasterProgram::layoutVertex({ geomCoords[1].x, geomCoords[1].y }, { util::EXTENT, 0 }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[3].x, geomCoords[3].y }, { 0, 32767 }));
+ RasterProgram::layoutVertex({ geomCoords[3].x, geomCoords[3].y }, { 0, util::EXTENT }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[2].x, geomCoords[2].y }, { 32767, 32767 }));
+ RasterProgram::layoutVertex({ geomCoords[2].x, geomCoords[2].y }, { util::EXTENT, util::EXTENT }));
bucket->indices.emplace_back(0, 1, 2);
bucket->indices.emplace_back(1, 2, 3);
diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp
index fc1a462090..7b69d09fa7 100644
--- a/src/mbgl/renderer/sources/render_image_source.hpp
+++ b/src/mbgl/renderer/sources/render_image_source.hpp
@@ -31,7 +31,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final;
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final;
diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp
index cbd874f647..bcd719365d 100644
--- a/src/mbgl/renderer/sources/render_raster_source.cpp
+++ b/src/mbgl/renderer/sources/render_raster_source.cpp
@@ -73,7 +73,7 @@ std::vector<std::reference_wrapper<RenderTile>> RenderRasterSource::getRenderTil
std::unordered_map<std::string, std::vector<Feature>>
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const RenderStyle&,
+ const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) const {
return std::unordered_map<std::string, std::vector<Feature>> {};
}
diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp
index 1f4678da9f..01de812309 100644
--- a/src/mbgl/renderer/sources/render_raster_source.hpp
+++ b/src/mbgl/renderer/sources/render_raster_source.hpp
@@ -26,7 +26,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final;
std::vector<Feature>
diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp
index 47bccdaca8..ca3071c6b0 100644
--- a/src/mbgl/renderer/sources/render_vector_source.cpp
+++ b/src/mbgl/renderer/sources/render_vector_source.cpp
@@ -76,9 +76,9 @@ std::vector<std::reference_wrapper<RenderTile>> RenderVectorSource::getRenderTil
std::unordered_map<std::string, std::vector<Feature>>
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {
- return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options);
+ return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
}
std::vector<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const {
diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp
index 256ad4e800..5e5c6d1108 100644
--- a/src/mbgl/renderer/sources/render_vector_source.hpp
+++ b/src/mbgl/renderer/sources/render_vector_source.hpp
@@ -26,7 +26,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final;
std::vector<Feature>
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index 219f154675..6cd9bd9ebd 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -171,7 +171,26 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
cache.setSize(conservativeCacheSize);
}
- removeStaleTiles(retain);
+ // Remove stale tiles. This goes through the (sorted!) tiles map and retain set in lockstep
+ // and removes items from tiles that don't have the corresponding key in the retain set.
+ {
+ auto tilesIt = tiles.begin();
+ auto retainIt = retain.begin();
+ while (tilesIt != tiles.end()) {
+ if (retainIt == retain.end() || tilesIt->first < *retainIt) {
+ if (!needsRelayout) {
+ tilesIt->second->setNecessity(Tile::Necessity::Optional);
+ cache.add(tilesIt->first, std::move(tilesIt->second));
+ }
+ tiles.erase(tilesIt++);
+ } else {
+ if (!(*retainIt < tilesIt->first)) {
+ ++tilesIt;
+ }
+ ++retainIt;
+ }
+ }
+ }
for (auto& pair : tiles) {
const PlacementConfig config { parameters.transformState.getAngle(),
@@ -184,29 +203,9 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
}
}
-// Moves all tiles to the cache except for those specified in the retain set.
-void TilePyramid::removeStaleTiles(const std::set<OverscaledTileID>& retain) {
- // Remove stale tiles. This goes through the (sorted!) tiles map and retain set in lockstep
- // and removes items from tiles that don't have the corresponding key in the retain set.
- auto tilesIt = tiles.begin();
- auto retainIt = retain.begin();
- while (tilesIt != tiles.end()) {
- if (retainIt == retain.end() || tilesIt->first < *retainIt) {
- tilesIt->second->setNecessity(Tile::Necessity::Optional);
- cache.add(tilesIt->first, std::move(tilesIt->second));
- tiles.erase(tilesIt++);
- } else {
- if (!(*retainIt < tilesIt->first)) {
- ++tilesIt;
- }
- ++retainIt;
- }
- }
-}
-
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {
std::unordered_map<std::string, std::vector<Feature>> result;
if (renderTiles.empty() || geometry.empty()) {
@@ -249,7 +248,7 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
renderTile.tile.queryRenderedFeatures(result,
tileSpaceQueryGeometry,
transformState,
- style,
+ layers,
options);
}
diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp
index d940f378fa..73a8d34c1c 100644
--- a/src/mbgl/renderer/tile_pyramid.hpp
+++ b/src/mbgl/renderer/tile_pyramid.hpp
@@ -21,7 +21,7 @@ namespace mbgl {
class PaintParameters;
class TransformState;
class RenderTile;
-class RenderStyle;
+class RenderLayer;
class RenderedQueryOptions;
class SourceQueryOptions;
class TileParameters;
@@ -50,7 +50,7 @@ public:
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
- const RenderStyle& style,
+ const std::vector<const RenderLayer*>&,
const RenderedQueryOptions& options) const;
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;
@@ -63,8 +63,6 @@ public:
bool enabled = false;
- void removeStaleTiles(const std::set<OverscaledTileID>&);
-
std::map<OverscaledTileID, std::unique_ptr<Tile>> tiles;
TileCache cache;
diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp
index 181b11784d..b54abc050d 100644
--- a/src/mbgl/renderer/update_parameters.hpp
+++ b/src/mbgl/renderer/update_parameters.hpp
@@ -13,8 +13,6 @@
namespace mbgl {
-class Scheduler;
-class FileSource;
class AnnotationManager;
class UpdateParameters {
@@ -34,8 +32,6 @@ public:
const Immutable<std::vector<Immutable<style::Source::Impl>>> sources;
const Immutable<std::vector<Immutable<style::Layer::Impl>>> layers;
- Scheduler& scheduler;
- FileSource& fileSource;
AnnotationManager& annotationManager;
const uint8_t prefetchZoomDelta;