diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index d52e6f858..3fffbe93a 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -87,16 +87,18 @@ gfx::DepthMode PaintParameters::depthModeFor3D() const { void PaintParameters::clearStencil() { nextStencilID = 1; context.clearStencilBuffer(0b00000000); + tileClippingMaskIDs.clear(); } namespace { +template +using GetTileIDFunc = std::function; +using TileMaskIDMap = std::map; + // Detects a difference in keys of renderTiles and tileClippingMaskIDs template -bool tileIDsIdentical(TIter beg, - TIter end, - std::function& f, - const std::map& idMap) { +bool tileIDsIdentical(TIter beg, TIter end, GetTileIDFunc& f, const TileMaskIDMap& idMap) { if (static_cast(std::distance(beg, end)) != idMap.size()) { return false; } @@ -108,23 +110,23 @@ bool tileIDsIdentical(TIter beg, void PaintParameters::renderTileClippingMasks(const std::set& tileIDs) { renderTileClippingMasks( - tileIDs.cbegin(), tileIDs.cend(), [](const UnwrappedTileID& ii) -> const UnwrappedTileID& { return ii; }); + tileIDs.cbegin(), tileIDs.cend(), [](const auto& ii) -> const UnwrappedTileID& { return ii; }); } void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) { renderTileClippingMasks((*renderTiles).cbegin(), (*renderTiles).cend(), - [](const std::reference_wrapper& ii) -> const UnwrappedTileID& { - const RenderTile& tile = ii.get(); - return tile.id; - }); + [](const auto& ii) -> const UnwrappedTileID& { return ii.get().id; }); +} + +void PaintParameters::clearTileClippingMasks() { + if (!tileClippingMaskIDs.empty()) { + clearStencil(); + } } template -void PaintParameters::renderTileClippingMasks( - TIter beg, - TIter end, - std::function::value_type&)>&& f) { +void PaintParameters::renderTileClippingMasks(TIter beg, TIter end, GetTileIDFunc&& f) { if (tileIDsIdentical(beg, end, f, tileClippingMaskIDs)) { // The current stencil mask is for this source already; no need to draw another one. return; @@ -136,8 +138,6 @@ void PaintParameters::renderTileClippingMasks( clearStencil(); } - tileClippingMaskIDs.clear(); - auto program = staticData.shaders->get(); if (!program) { return; diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index 7aaf54454..df49d109c 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -96,6 +96,7 @@ public: public: void renderTileClippingMasks(const RenderTiles&); void renderTileClippingMasks(const std::set&); + void clearTileClippingMasks(); gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const; gfx::StencilMode stencilModeFor3D(); @@ -104,10 +105,9 @@ private: void clearStencil(); template - void renderTileClippingMasks( - TIter beg, - TIter end, - std::function::value_type&)>&&); + using GetTileIDFunc = std::function; + template + void renderTileClippingMasks(TIter beg, TIter end, GetTileIDFunc&&); // This needs to be an ordered map so that we have the same order as the renderTiles. std::map tileClippingMaskIDs; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index e278dcb3e..1c713040f 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -263,24 +263,30 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Composite (Opaque+Translucent) on bottom platform::glScissor(0, 0, halfW, halfH); + // Clipping masks were drawn only on the other side + parameters.clearTileClippingMasks(); drawableTranslucentPass(); // RenderLayers on the right // Opaque only on top platform::glScissor(halfW, 0, halfW, H); + parameters.clearTileClippingMasks(); renderLayerOpaquePass(); // Composite (Opaque+Translucent) on bottom platform::glScissor(halfW, 0, halfW, halfH); + parameters.clearTileClippingMasks(); renderLayerTranslucentPass(); #else // Drawable LayerGroups on the left platform::glScissor(0, 0, halfW, H); + parameters.clearTileClippingMasks(); drawableOpaquePass(); drawableTranslucentPass(); // RenderLayers on the right platform::glScissor(halfW, 0, W, H); + parameters.clearTileClippingMasks(); renderLayerOpaquePass(); renderLayerTranslucentPass(); #endif