Refactor clipping mask rendering (#1209)
This commit is contained in:
committed by
Bart Louwers
parent
172cc0a43f
commit
00d6bdd2ae
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user