Refactor clipping mask rendering (#1209)

This commit is contained in:
Tim Sylvester
2023-06-06 14:15:40 -07:00
committed by Bart Louwers
parent 172cc0a43f
commit 00d6bdd2ae
19 changed files with 180 additions and 88 deletions

View File

@@ -108,6 +108,10 @@ public:
bool getEnabled() const { return enabled; }
void setEnabled(bool value) { enabled = value; }
/// Whether to do stenciling (based on the Tile ID)
bool getNeedsStencil() const { return needsStencil; }
void setNeedsStencil(bool value) { needsStencil = value; }
/// not used for anything yet
DrawPriority getDrawPriority() const { return drawPriority; }
void setDrawPriority(DrawPriority value) { drawPriority = value; }
@@ -155,6 +159,7 @@ public:
protected:
bool enabled = true;
bool needsStencil = false;
std::string name;
util::SimpleIdentity uniqueID;
gfx::ShaderProgramBasePtr shader;

View File

@@ -84,6 +84,10 @@ public:
float getLineWidth() const { return lineWidth; }
void setLineWidth(float value) { lineWidth = value; }
/// Whether to do stenciling (based on the Tile ID)
bool getNeedsStencil() const { return needsStencil; }
void setNeedsStencil(bool value) { needsStencil = value; }
DepthMaskType getDepthType() const { return depthType; }
void setDepthType(DepthMaskType value) { depthType = value; }
@@ -156,6 +160,7 @@ protected:
std::string vertexAttrName;
std::string colorAttrName;
mbgl::RenderPass renderPass;
bool needsStencil = false;
float lineWidth = 1.0f;
DrawPriority drawPriority = 0;
int32_t subLayerIndex = 0;

View File

@@ -10,7 +10,7 @@ namespace gl {
*/
class TileLayerGroupGL : public TileLayerGroup {
public:
TileLayerGroupGL(int32_t layerIndex, std::size_t initialCapacity);
TileLayerGroupGL(int32_t layerIndex, std::size_t initialCapacity, std::string name);
~TileLayerGroupGL() override {}
void upload(gfx::UploadPass&) override;

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace mbgl {
@@ -33,7 +34,7 @@ using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
*/
class LayerGroup : public util::SimpleIdentifiable {
protected:
LayerGroup(int32_t layerIndex);
LayerGroup(int32_t layerIndex, std::string name = std::string());
public:
LayerGroup(const LayerGroup&) = delete;
@@ -43,8 +44,14 @@ public:
bool getEnabled() const { return enabled; }
void setEnabled(bool value) { enabled = value; }
const std::string& getName() const { return name; }
void setName(std::string value) { name = std::move(value); }
int32_t getLayerIndex() const { return layerIndex; }
virtual std::size_t getDrawableCount() const = 0;
bool empty() const { return getDrawableCount() == 0; }
/// Called before starting each frame
virtual void preRender(RenderOrchestrator&, PaintParameters&) {}
/// Called during the upload pass
@@ -71,6 +78,7 @@ protected:
bool enabled = true;
int32_t layerIndex;
LayerTweakerPtr layerTweaker;
std::string name;
};
/**
@@ -78,12 +86,12 @@ protected:
*/
class TileLayerGroup : public LayerGroup {
public:
TileLayerGroup(int32_t layerIndex, std::size_t initialCapacity);
TileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name);
~TileLayerGroup() override;
void updateLayerIndex(int32_t newLayerIndex);
std::size_t getDrawableCount() const;
std::size_t getDrawableCount() const override;
std::size_t getDrawableCount(mbgl::RenderPass, const OverscaledTileID&) const;
std::vector<gfx::UniqueDrawable> removeDrawables(mbgl::RenderPass, const OverscaledTileID&);

View File

@@ -116,7 +116,9 @@ public:
virtual gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) = 0;
/// Create a layer group implementation
virtual TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity) = 0;
virtual TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex,
std::size_t initialCapacity,
std::string name) = 0;
/// Create a texture
virtual Texture2DPtr createTexture2D() = 0;

View File

@@ -42,6 +42,7 @@ void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
const auto& draw = getCurrentDrawable(/*createIfNone=*/true);
draw->setLineWidth(static_cast<int32_t>(lineWidth));
draw->setNeedsStencil(needsStencil);
draw->setRenderPass(renderPass);
draw->setDrawPriority(drawPriority);
draw->setSubLayerIndex(subLayerIndex);

View File

@@ -471,8 +471,8 @@ gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders
return shaders.get<gl::ShaderProgramGL>(name);
}
TileLayerGroupPtr Context::createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity) {
return std::make_shared<TileLayerGroupGL>(layerIndex, initialCapacity);
TileLayerGroupPtr Context::createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) {
return std::make_shared<TileLayerGroupGL>(layerIndex, initialCapacity, std::move(name));
}
gfx::Texture2DPtr Context::createTexture2D() {

View File

@@ -109,7 +109,7 @@ public:
gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override;
TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity) override;
TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override;
gfx::Texture2DPtr createTexture2D() override;

View File

@@ -41,10 +41,8 @@ void DrawableGL::draw(const PaintParameters& parameters) const {
// force disable depth test for debugging
// setDepthMode({gfx::DepthFunctionType::Always, gfx::DepthMaskType::ReadOnly, {0,1}});
if (tileID) {
// Doesn't work until the clipping masks are generated
// parameters.stencilModeForClipping(tileID->toUnwrapped());
context.setStencilMode(gfx::StencilMode::disabled());
if (needsStencil && tileID) {
context.setStencilMode(parameters.stencilModeForClipping(tileID->toUnwrapped()));
} else {
context.setStencilMode(gfx::StencilMode::disabled());
}

View File

@@ -12,8 +12,8 @@
namespace mbgl {
namespace gl {
TileLayerGroupGL::TileLayerGroupGL(int32_t layerIndex_, std::size_t initialCapacity)
: TileLayerGroup(layerIndex_, initialCapacity) {}
TileLayerGroupGL::TileLayerGroupGL(int32_t layerIndex_, std::size_t initialCapacity, std::string name_)
: TileLayerGroup(layerIndex_, initialCapacity, std::move(name_)) {}
void TileLayerGroupGL::upload(gfx::UploadPass& uploadPass) {
if (!enabled) {
@@ -45,6 +45,23 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
return;
}
if (getDrawableCount()) {
#if !defined(NDEBUG)
const auto label = getName() + (getName().empty() ? "" : "-") + "tile-clip-masks";
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
// Collect the tile IDs relevant to stenciling and update the stencil buffer, if necessary.
std::set<UnwrappedTileID> tileIDs;
observeDrawables([&](const gfx::Drawable& drawable) {
if (drawable.getEnabled() && drawable.getNeedsStencil() && drawable.getTileID() &&
drawable.hasRenderPass(parameters.pass)) {
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
}
});
parameters.renderTileClippingMasks(tileIDs);
}
observeDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getEnabled() || !drawable.hasRenderPass(parameters.pass)) {
return;

View File

@@ -29,11 +29,12 @@ struct TileLayerGroup::Impl {
TileMap tileDrawables;
};
LayerGroup::LayerGroup(int32_t layerIndex_)
: layerIndex(layerIndex_) {}
LayerGroup::LayerGroup(int32_t layerIndex_, std::string name_)
: layerIndex(layerIndex_),
name(std::move(name_)) {}
TileLayerGroup::TileLayerGroup(int32_t layerIndex_, std::size_t initialCapacity)
: LayerGroup(layerIndex_),
TileLayerGroup::TileLayerGroup(int32_t layerIndex_, std::size_t initialCapacity, std::string name_)
: LayerGroup(layerIndex_, std::move(name_)),
impl(std::make_unique<Impl>(initialCapacity)) {}
TileLayerGroup::~TileLayerGroup() {}

View File

@@ -54,6 +54,16 @@ static constexpr std::string_view BackgroundLayerUBOName = "BackgroundLayerUBO";
void BackgroundLayerTweaker::execute(LayerGroup& layerGroup, const RenderTree&, const PaintParameters& parameters) {
const auto& state = parameters.state;
auto& context = parameters.context;
if (layerGroup.empty()) {
return;
}
#if defined(DEBUG)
const auto label = layerGroup.getName() + "-update-uniforms";
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
const auto& crossfade = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).crossfade;
const bool hasPattern = !evaluated.get<BackgroundPattern>().to.empty();

View File

@@ -57,6 +57,15 @@ void CircleLayerTweaker::execute(LayerGroup& layerGroup,
const PaintParameters& parameters) {
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
if (layerGroup.empty()) {
return;
}
#if !defined(NDEBUG)
const auto label = layerGroup.getName() + "-update-uniforms";
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
CirclePaintParamsUBO paintParamsUBO;
paintParamsUBO.camera_to_center_distance = parameters.state.getCameraToCenterDistance();
paintParamsUBO.device_pixel_ratio = parameters.pixelRatio;

View File

@@ -60,6 +60,15 @@ void FillLayerTweaker::execute(LayerGroup& layerGroup,
const auto& evaluated = props.evaluated;
const auto& crossfade = props.crossfade;
if (layerGroup.empty()) {
return;
}
#if !defined(NDEBUG)
const auto label = layerGroup.getName() + "-update-uniforms";
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID()) {
return;

View File

@@ -250,7 +250,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
}
if (!tileLayerGroup) {
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
if (!tileLayerGroup) {
return;
}

View File

@@ -272,7 +272,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!tileLayerGroup) {
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
if (!tileLayerGroup) {
return;
}

View File

@@ -293,7 +293,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!tileLayerGroup) {
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
if (!tileLayerGroup) {
return;
}
@@ -339,6 +339,12 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
};
const auto commonInit = [](gfx::DrawableBuilder& builder) {
builder.setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
builder.setCullFaceMode(gfx::CullFaceMode::disabled());
builder.setNeedsStencil(true);
};
for (const auto renderPass : {RenderPass::Opaque, RenderPass::Translucent}) {
if (!(mbgl::underlying_type(renderPass) & evaluatedProperties->renderPasses)) {
continue;
@@ -355,6 +361,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
});
constexpr auto samplerLocation = 0;
const auto layerPrefix = getID() + "/";
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
@@ -454,34 +461,30 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
if (doFill && !fillBuilder && fillShader) {
fillBuilder = context.createDrawableBuilder("fill");
fillBuilder->setShader(fillShader);
fillBuilder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
fillBuilder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill")) {
commonInit(*builder);
builder->setShader(fillShader);
builder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
: gfx::DepthMaskType::ReadOnly);
fillBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setSubLayerIndex(0);
fillBuilder = std::move(builder);
}
}
if (doOutline && !outlineBuilder && outlineShader) {
outlineBuilder = context.createDrawableBuilder("fill-outline");
outlineBuilder->setShader(outlineShader);
outlineBuilder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
outlineBuilder->setLineWidth(2.0f);
outlineBuilder->setDepthType(gfx::DepthMaskType::ReadOnly);
outlineBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
outlineBuilder->setSubLayerIndex(unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0);
}
if (fillBuilder) {
fillBuilder->setRenderPass(renderPass);
fillBuilder->setVertexAttributes(fillVertexAttrs);
}
if (outlineBuilder) {
outlineBuilder->setRenderPass(renderPass);
outlineBuilder->setVertexAttributes(outlineVertexAttrs);
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-outline")) {
commonInit(*builder);
builder->setShader(outlineShader);
builder->setLineWidth(2.0f);
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setSubLayerIndex(unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0);
outlineBuilder = std::move(builder);
}
}
if (fillBuilder) {
buildVertices();
fillBuilder->setRenderPass(renderPass);
fillBuilder->setVertexAttributes(fillVertexAttrs);
fillBuilder->addVertices(rawVerts, 0, rawVerts.size());
fillBuilder->setSegments(
gfx::Triangles(),
@@ -491,6 +494,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
if (outlineBuilder) {
buildVertices();
outlineBuilder->setRenderPass(renderPass);
outlineBuilder->setVertexAttributes(outlineVertexAttrs);
outlineBuilder->addVertices(rawVerts, 0, rawVerts.size());
outlineBuilder->setSegments(
gfx::Lines(2),
@@ -547,40 +552,35 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// }
if (!patternBuilder && patternShader) {
patternBuilder = context.createDrawableBuilder("fill-pattern");
patternBuilder->setShader(fillShader);
patternBuilder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
patternBuilder->setDepthType(gfx::DepthMaskType::ReadWrite);
patternBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
patternBuilder->setSubLayerIndex(1);
if (auto& tex = tile.getIconAtlasTexture()) {
patternBuilder->setTexture(tex, samplerLocation);
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-pattern")) {
commonInit(*builder);
builder->setShader(fillShader);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
builder->setSubLayerIndex(1);
if (auto& tex = tile.getIconAtlasTexture()) {
builder->setTexture(tex, samplerLocation);
}
patternBuilder = std::move(builder);
}
}
if (doOutline && !outlinePatternBuilder && outlinePatternShader) {
outlinePatternBuilder = context.createDrawableBuilder("fill-outline-pattern");
outlinePatternBuilder->setShader(outlineShader);
outlinePatternBuilder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
outlinePatternBuilder->setLineWidth(2.0f);
outlinePatternBuilder->setDepthType(gfx::DepthMaskType::ReadOnly);
outlinePatternBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
outlinePatternBuilder->setSubLayerIndex(2);
if (auto& tex = tile.getIconAtlasTexture()) {
patternBuilder->setTexture(tex, samplerLocation);
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-outline-pattern")) {
commonInit(*builder);
builder->setShader(outlineShader);
builder->setLineWidth(2.0f);
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setSubLayerIndex(2);
if (auto& tex = tile.getIconAtlasTexture()) {
builder->setTexture(tex, samplerLocation);
}
outlinePatternBuilder = std::move(builder);
}
}
if (patternBuilder) {
patternBuilder->setRenderPass(renderPass);
patternBuilder->setVertexAttributes(fillVertexAttrs);
}
if (outlinePatternBuilder) {
outlinePatternBuilder->setRenderPass(renderPass);
outlinePatternBuilder->setVertexAttributes(outlineVertexAttrs);
}
if (patternBuilder) {
buildVertices();
patternBuilder->setRenderPass(renderPass);
patternBuilder->setVertexAttributes(fillVertexAttrs);
patternBuilder->addVertices(rawVerts, 0, rawVerts.size());
patternBuilder->setSegments(
gfx::Triangles(),
@@ -590,6 +590,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
if (outlinePatternBuilder) {
buildVertices();
outlinePatternBuilder->setRenderPass(renderPass);
outlinePatternBuilder->setVertexAttributes(outlineVertexAttrs);
outlinePatternBuilder->addVertices(rawVerts, 0, rawVerts.size());
outlinePatternBuilder->setSegments(
gfx::Lines(2),
@@ -597,8 +599,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
reinterpret_cast<const std::vector<Segment<void>>&>(bucket.lineSegments));
finish(*outlinePatternBuilder, renderPass, tileID);
}
// checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
}
}
}

View File

@@ -92,29 +92,44 @@ void PaintParameters::clearStencil() {
namespace {
// Detects a difference in keys of renderTiles and tileClippingMaskIDs
bool tileIDsIdentical(const RenderTiles& renderTiles, const std::map<UnwrappedTileID, int32_t>& tileClippingMaskIDs) {
assert(renderTiles);
assert(std::is_sorted(renderTiles->begin(), renderTiles->end(), [](const RenderTile& a, const RenderTile& b) {
return a.id < b.id;
}));
if (renderTiles->size() != tileClippingMaskIDs.size()) {
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) {
if (static_cast<std::size_t>(std::distance(beg, end)) != idMap.size()) {
return false;
}
return std::equal(
renderTiles->begin(), renderTiles->end(), tileClippingMaskIDs.begin(), [](const RenderTile& a, const auto& b) {
return a.id == b.first;
});
assert(std::is_sorted(beg, end, [&f](const auto& a, const auto& b) { return f(a) < f(b); }));
return std::equal(beg, end, idMap.cbegin(), [&f](const auto& ii, const auto& pair) { return f(ii) == pair.first; });
}
} // namespace
void PaintParameters::renderTileClippingMasks(const std::set<UnwrappedTileID>& tileIDs) {
renderTileClippingMasks(
tileIDs.cbegin(), tileIDs.cend(), [](const UnwrappedTileID& ii) -> const UnwrappedTileID& { return ii; });
}
void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
if (!renderTiles || renderTiles->empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) {
renderTileClippingMasks((*renderTiles).cbegin(),
(*renderTiles).cend(),
[](const std::reference_wrapper<const RenderTile>& ii) -> const UnwrappedTileID& {
const RenderTile& tile = ii.get();
return tile.id;
});
}
template <typename TIter>
void PaintParameters::renderTileClippingMasks(
TIter beg, TIter end, std::function<UnwrappedTileID(const typename std::iterator_traits<TIter>::value_type&)> f) {
if (tileIDsIdentical(beg, end, f, tileClippingMaskIDs)) {
// The current stencil mask is for this source already; no need to draw another one.
return;
}
if (nextStencilID + renderTiles->size() > 256) {
const auto count = std::distance(beg, end);
if (nextStencilID + count > maxStencilValue) {
// we'll run out of fresh IDs so we need to clear and start from scratch
clearStencil();
}
@@ -129,9 +144,11 @@ void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
const style::Properties<>::PossiblyEvaluated properties{};
const ClippingMaskProgram::Binders paintAttributeData(properties, 0);
for (const RenderTile& renderTile : *renderTiles) {
for (auto i = beg; i != end; ++i) {
const auto& tileID = f(*i);
const int32_t stencilID = nextStencilID++;
tileClippingMaskIDs.emplace(renderTile.id, stencilID);
tileClippingMaskIDs.emplace(tileID, stencilID);
program->draw(context,
*renderPass,
@@ -149,7 +166,7 @@ void PaintParameters::renderTileClippingMasks(const RenderTiles& renderTiles) {
staticData.clippingMaskSegments,
ClippingMaskProgram::computeAllUniformValues(
ClippingMaskProgram::LayoutUniformValues{
uniforms::matrix::Value(matrixForTile(renderTile.id)),
uniforms::matrix::Value(matrixForTile(tileID)),
},
paintAttributeData,
properties,
@@ -174,7 +191,7 @@ gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID&
}
gfx::StencilMode PaintParameters::stencilModeFor3D() {
if (nextStencilID + 1 > 256) {
if (nextStencilID + 1 > maxStencilValue) {
clearStencil();
}
@@ -193,7 +210,7 @@ gfx::StencilMode PaintParameters::stencilModeFor3D() {
gfx::ColorMode PaintParameters::colorModeForRenderPass() const {
if (debugOptions & MapDebugOptions::Overdraw) {
const float overdraw = 1.0f / 8.0f;
constexpr float overdraw = 1.0f / 8.0f;
return gfx::ColorMode{
gfx::ColorMode::Add{gfx::ColorBlendFactorType::ConstantColor, gfx::ColorBlendFactorType::One},
Color{overdraw, overdraw, overdraw, 0.0f},

View File

@@ -11,7 +11,10 @@
#include <mbgl/util/mat4.hpp>
#include <array>
#include <functional>
#include <iterator>
#include <map>
#include <set>
#include <vector>
namespace mbgl {
@@ -92,12 +95,18 @@ public:
// Stencil handling
public:
void renderTileClippingMasks(const RenderTiles&);
void renderTileClippingMasks(const std::set<UnwrappedTileID>&);
gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const;
gfx::StencilMode stencilModeFor3D();
private:
void clearStencil();
template <typename TIter>
void renderTileClippingMasks(
TIter beg, TIter end, std::function<UnwrappedTileID(const typename std::iterator_traits<TIter>::value_type&)>);
// This needs to be an ordered map so that we have the same order as the renderTiles.
std::map<UnwrappedTileID, int32_t> tileClippingMaskIDs;
int32_t nextStencilID = 1;
@@ -106,7 +115,8 @@ public:
int numSublayers = 3;
uint32_t currentLayer;
float depthRangeSize;
const float depthEpsilon = 1.0f / (1 << 16);
static constexpr float depthEpsilon = 1.0f / (1 << 16);
static constexpr int maxStencilValue = 255;
uint32_t opaquePassCutoff = 0;
float symbolFadeChange;
};