Drawable Renderer (#1570), Fix rendering problems due to tile clip masks being limited by split-view by clearing the state after changing the view.

Somewhat less verbose typing in clip mask tile ID handling.
This commit is contained in:
Tim Sylvester
2023-06-07 09:24:50 -07:00
committed by Bart Louwers
parent 2e489ebd3e
commit 826f17b659
3 changed files with 25 additions and 19 deletions

View File

@@ -87,16 +87,18 @@ gfx::DepthMode PaintParameters::depthModeFor3D() const {
void PaintParameters::clearStencil() {
nextStencilID = 1;
context.clearStencilBuffer(0b00000000);
tileClippingMaskIDs.clear();
}
namespace {
template <typename TIter>
using GetTileIDFunc = std::function<const UnwrappedTileID&(const typename TIter::value_type&)>;
using TileMaskIDMap = std::map<UnwrappedTileID, int32_t>;
// Detects a difference in keys of renderTiles and tileClippingMaskIDs
template <typename TIter>
bool tileIDsIdentical(TIter beg,
TIter end,
std::function<const UnwrappedTileID&(const typename TIter::value_type&)>& f,
const std::map<UnwrappedTileID, int32_t>& idMap) {
bool tileIDsIdentical(TIter beg, TIter end, GetTileIDFunc<TIter>& f, const TileMaskIDMap& idMap) {
if (static_cast<std::size_t>(std::distance(beg, end)) != idMap.size()) {
return false;
}
@@ -108,23 +110,23 @@ bool tileIDsIdentical(TIter beg,
void PaintParameters::renderTileClippingMasks(const std::set<UnwrappedTileID>& 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<const RenderTile>& 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 <typename TIter>
void PaintParameters::renderTileClippingMasks(
TIter beg,
TIter end,
std::function<const UnwrappedTileID&(const typename std::iterator_traits<TIter>::value_type&)>&& f) {
void PaintParameters::renderTileClippingMasks(TIter beg, TIter end, GetTileIDFunc<TIter>&& 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<ClippingMaskProgram>();
if (!program) {
return;

View File

@@ -96,6 +96,7 @@ public:
public:
void renderTileClippingMasks(const RenderTiles&);
void renderTileClippingMasks(const std::set<UnwrappedTileID>&);
void clearTileClippingMasks();
gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const;
gfx::StencilMode stencilModeFor3D();
@@ -104,10 +105,9 @@ private:
void clearStencil();
template <typename TIter>
void renderTileClippingMasks(
TIter beg,
TIter end,
std::function<const UnwrappedTileID&(const typename std::iterator_traits<TIter>::value_type&)>&&);
using GetTileIDFunc = std::function<const UnwrappedTileID&(const typename TIter::value_type&)>;
template <typename TIter>
void renderTileClippingMasks(TIter beg, TIter end, GetTileIDFunc<TIter>&&);
// This needs to be an ordered map so that we have the same order as the renderTiles.
std::map<UnwrappedTileID, int32_t> tileClippingMaskIDs;

View File

@@ -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