summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksandar Stojiljkovic <aleksandar.stojiljkovic@mapbox.com>2019-07-07 13:40:22 +0300
committerAleksandar Stojiljkovic <aleksandar.stojiljkovic@mapbox.com>2019-07-09 15:13:38 +0200
commit2c5528e691b502673b16723205c83add62317734 (patch)
treed4e27fecc8b867a5472e5392f52953f38c9327d7 /src
parent929824ecc3176c01a5f3e74d80e2ae2ba2cf1e51 (diff)
downloadqtlocation-mapboxgl-2c5528e691b502673b16723205c83add62317734.tar.gz
Fix layers rendering after fill-extrusion
This fixes following issues: * Fix some false passing combinations/fill-extrusion-translucent--XXXX tests * Fix and enable other, failing but ignored, combinations/fill-extrusion-translucent--XXXX tests * Fix rendering of layers that are on top of fill-extrusion layers state.getProjMatrix(nearClippedProjMatrix, 100) caused that tests with size 64x64 were not rendering fill extrusions: far plane calculated as 96.9 and near plane set to 100 was the cause. near plane is changed from hardcoded 100 to depend on state.getCameraToCenterDistance() - producing similar value but one that follows max zoom. This caused that e.g. combinations/fill-extrusion-translucent--fill-opaque was falsely passing as only fill-opaque layer got rendered. combinations/fill-extrusion-translucent--XXXX tests expose regression https://github.com/mapbox/mapbox-gl-native/issues/14844#issuecomment-503600034 in #14844, #14779. Fix (opaquePassCutoff, is3D) is ported from https://github.com/mapbox/mapbox-gl-js/pull/7821 Fixes: #14844, #14779, #15039
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp4
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp1
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp9
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp12
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp3
-rw-r--r--src/mbgl/renderer/render_layer.hpp3
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp10
-rw-r--r--src/mbgl/renderer/render_tile.cpp2
-rw-r--r--src/mbgl/renderer/render_tree.hpp1
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp1
10 files changed, 31 insertions, 15 deletions
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index b8d195cfa1..5ad2e53a5b 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -55,6 +55,10 @@ bool RenderFillExtrusionLayer::hasCrossfade() const {
return getCrossfade<FillExtrusionLayerProperties>(evaluatedProperties).t != 1;
}
+bool RenderFillExtrusionLayer::is3D() const {
+ return true;
+}
+
void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
assert(renderTiles);
if (parameters.pass != RenderPass::Translucent) {
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
index 9118601581..8bd1f52adf 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
@@ -17,6 +17,7 @@ private:
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
+ bool is3D() const override;
void render(PaintParameters&) override;
bool queryIntersectsFeature(
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp
index 6a3c247fbb..c2bf149582 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.cpp
@@ -130,11 +130,10 @@ void RenderFillLayer::render(PaintParameters& parameters) {
);
};
- // 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 (bucket.triangleIndexBuffer &&
- (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
- evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) {
+ auto fillRenderPass = (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f
+ && evaluated.get<FillOpacity>().constantOr(0) >= 1.0f
+ && parameters.currentLayer >= parameters.opaquePassCutoff) ? RenderPass::Opaque : RenderPass::Translucent;
+ if (bucket.triangleIndexBuffer && parameters.pass == fillRenderPass) {
draw(parameters.programs.getFillLayerPrograms().fill,
gfx::Triangles(),
parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque
diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp
index 1539c0fbcb..6c6abc008b 100644
--- a/src/mbgl/renderer/paint_parameters.cpp
+++ b/src/mbgl/renderer/paint_parameters.cpp
@@ -19,10 +19,11 @@ TransformParameters::TransformParameters(const TransformState& state_)
// odd viewport sizes.
state.getProjMatrix(alignedProjMatrix, 1, true);
- // Calculate a second projection matrix with the near plane clipped to 100 so as
- // not to waste lots of depth buffer precision on very close empty space, for layer
- // types (fill-extrusion) that use the depth buffer to emulate real-world space.
- state.getProjMatrix(nearClippedProjMatrix, 100);
+ // Calculate a second projection matrix with the near plane moved further,
+ // to a tenth of the far value, so as not to waste depth buffer precision on
+ // very close empty space, for layer types (fill-extrusion) that use the
+ // depth buffer to emulate real-world space.
+ state.getProjMatrix(nearClippedProjMatrix, 0.1 * state.getCameraToCenterDistance());
}
PaintParameters::PaintParameters(gfx::Context& context_,
@@ -72,6 +73,9 @@ mat4 PaintParameters::matrixForTile(const UnwrappedTileID& tileID, bool aligned)
}
gfx::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gfx::DepthMaskType mask) const {
+ if (currentLayer < opaquePassCutoff) {
+ return gfx::DepthMode::disabled();
+ }
float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { depth, depth } };
}
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index a0d26df7c5..a043ad5578 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -104,8 +104,7 @@ public:
uint32_t currentLayer;
float depthRangeSize;
const float depthEpsilon = 1.0f / (1 << 16);
-
-
+ uint32_t opaquePassCutoff = 0;
float symbolFadeChange;
};
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index c7efdceab4..fe8b7c6529 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -66,6 +66,9 @@ public:
// Returns true if the layer has a pattern property and is actively crossfading.
virtual bool hasCrossfade() const = 0;
+ // Returns true if layer writes to depth buffer by drawing using PaintParameters::depthModeFor3D().
+ virtual bool is3D() const { return false; }
+
// Returns true is the layer is subject to placement.
bool needsPlacement() const;
diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp
index 7df74cda71..c70ce63c76 100644
--- a/src/mbgl/renderer/render_orchestrator.cpp
+++ b/src/mbgl/renderer/render_orchestrator.cpp
@@ -342,12 +342,16 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
}
}
- for (auto& renderItem : layerRenderItems) {
- RenderLayer& renderLayer = renderItem.layer;
- renderLayer.prepare({renderItem.source, *imageManager, *patternAtlas, *lineAtlas, updateParameters.transformState});
+ uint32_t i = static_cast<uint32_t>(layerRenderItems.size()) - 1;
+ for (auto it = layerRenderItems.begin(); it != layerRenderItems.end(); ++it, --i) {
+ RenderLayer& renderLayer = it->layer;
+ renderLayer.prepare({it->source, *imageManager, *patternAtlas, *lineAtlas, updateParameters.transformState});
if (renderLayer.needsPlacement()) {
layersNeedPlacement.emplace_back(renderLayer);
}
+ if (renderLayer.is3D() && renderTreeParameters->opaquePassCutOff == 0) {
+ renderTreeParameters->opaquePassCutOff = i;
+ }
}
// Symbol placement.
{
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index fbb2ae81de..65a6cb9f30 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -121,7 +121,7 @@ void RenderTile::prepare(const SourcePrepareParameters& parameters) {
}
// Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix
- // clips the near plane to 100 to save depth buffer precision
+ // has near plane moved further, to enhance depth buffer precision
const auto& transform = parameters.transform;
transform.state.matrixFor(matrix, id);
transform.state.matrixFor(nearClippedMatrix, id);
diff --git a/src/mbgl/renderer/render_tree.hpp b/src/mbgl/renderer/render_tree.hpp
index 4266ddec6d..cf62ccb03e 100644
--- a/src/mbgl/renderer/render_tree.hpp
+++ b/src/mbgl/renderer/render_tree.hpp
@@ -47,6 +47,7 @@ public:
TimePoint timePoint;
EvaluatedLight light;
bool has3D = false;
+ uint32_t opaquePassCutOff = 0;
Color backgroundColor;
float symbolFadeChange = 0.0f;
bool needsRepaint = false;
diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp
index c536497c30..990d9cd3ab 100644
--- a/src/mbgl/renderer/renderer_impl.cpp
+++ b/src/mbgl/renderer/renderer_impl.cpp
@@ -77,6 +77,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
};
parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange;
+ parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
const auto& sourceRenderItems = renderTree.getSourceRenderItems();
const auto& layerRenderItems = renderTree.getLayerRenderItems();