summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/paint_parameters.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/paint_parameters.cpp')
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp100
1 files changed, 91 insertions, 9 deletions
diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp
index 624deeec0a..e9f42d2579 100644
--- a/src/mbgl/renderer/paint_parameters.cpp
+++ b/src/mbgl/renderer/paint_parameters.cpp
@@ -1,8 +1,11 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/renderer/render_static_data.hpp>
+#include <mbgl/renderer/render_source.hpp>
+#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/gfx/command_encoder.hpp>
#include <mbgl/gfx/render_pass.hpp>
+#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/map/transform_state.hpp>
namespace mbgl {
@@ -73,15 +76,94 @@ gfx::DepthMode PaintParameters::depthModeFor3D(gfx::DepthMaskType mask) const {
return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { 0.0, 1.0 } };
}
-gfx::StencilMode PaintParameters::stencilModeForClipping(const ClipID& id) const {
- return gfx::StencilMode {
- gfx::StencilMode::Equal { static_cast<uint32_t>(id.mask.to_ulong()) },
- static_cast<int32_t>(id.reference.to_ulong()),
- 0,
- gfx::StencilOpType::Keep,
- gfx::StencilOpType::Keep,
- gfx::StencilOpType::Replace
- };
+void PaintParameters::clearStencil() {
+ nextStencilID = 1;
+ context.clearStencilBuffer(0b00000000);
+}
+
+namespace {
+
+// Detects a difference in keys of renderTiles and tileClippingMaskIDs
+bool tileIDsIdentical(const std::vector<std::reference_wrapper<RenderTile>>& renderTiles,
+ const std::map<UnwrappedTileID, int32_t>& tileClippingMaskIDs) {
+ assert(std::is_sorted(renderTiles.begin(), renderTiles.end(),
+ [](const RenderTile& a, const RenderTile& b) { return a.id < b.id; }));
+ if (renderTiles.size() != tileClippingMaskIDs.size()) {
+ return false;
+ }
+ return std::equal(renderTiles.begin(), renderTiles.end(), tileClippingMaskIDs.begin(),
+ [](const RenderTile& a, const auto& b) { return a.id == b.first; });
+}
+
+} // namespace
+
+void PaintParameters::renderTileClippingMasks(const std::vector<std::reference_wrapper<RenderTile>>& renderTiles) {
+ if (renderTiles.empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) {
+ // The current stencil mask is for this source already; no need to draw another one.
+ return;
+ }
+
+ if (nextStencilID + renderTiles.size() > 256) {
+ // we'll run out of fresh IDs so we need to clear and start from scratch
+ clearStencil();
+ }
+
+ tileClippingMaskIDs.clear();
+
+ auto& program = staticData.programs.clippingMask;
+ const style::Properties<>::PossiblyEvaluated properties {};
+ const ClippingMaskProgram::Binders paintAttributeData(properties, 0);
+
+ for (const RenderTile& renderTile : renderTiles) {
+ const int32_t stencilID = nextStencilID++;
+ tileClippingMaskIDs.emplace(renderTile.id, stencilID);
+
+ program.draw(
+ context,
+ *renderPass,
+ gfx::Triangles(),
+ gfx::DepthMode::disabled(),
+ gfx::StencilMode {
+ gfx::StencilMode::Always{},
+ stencilID,
+ 0b11111111,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Replace
+ },
+ gfx::ColorMode::disabled(),
+ gfx::CullFaceMode::disabled(),
+ staticData.quadTriangleIndexBuffer,
+ staticData.tileTriangleSegments,
+ program.computeAllUniformValues(
+ ClippingMaskProgram::LayoutUniformValues {
+ uniforms::matrix::Value( matrixForTile(renderTile.id) ),
+ },
+ paintAttributeData,
+ properties,
+ state.getZoom()
+ ),
+ program.computeAllAttributeBindings(
+ staticData.tileVertexBuffer,
+ paintAttributeData,
+ properties
+ ),
+ ClippingMaskProgram::TextureBindings{},
+ "clipping"
+ );
+ }
+}
+
+gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID& tileID) const {
+ auto it = tileClippingMaskIDs.find(tileID);
+ assert(it != tileClippingMaskIDs.end());
+ const int32_t id = it != tileClippingMaskIDs.end() ? it->second : 0b00000000;
+ return gfx::StencilMode{ gfx::StencilMode::Equal{ 0b11111111 },
+ id,
+ 0b00000000,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Keep,
+ gfx::StencilOpType::Replace };
}
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {