Merge branch 'topic/metal-sep21' into main (#1695)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: Alex Cristici <alex.cristici@gmail.com>
Co-authored-by: Stefan Karschti <stefan.karschti@gmail.com>
Co-authored-by: Alex Cristici <alex@skoon.energy>
Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
Co-authored-by: Wei Chen <alanchenboy@gmail.com>
Co-authored-by: Siarhei Fedartsou <siarhei.fedartsou@gmail.com>
Co-authored-by: tdcosta100 <tdcosta100@gmail.com>
This commit is contained in:
mwilsnd
2023-10-02 09:22:19 -04:00
committed by GitHub
parent 34a2097bdd
commit f4d3cb6b69
48 changed files with 754 additions and 576 deletions

View File

@@ -18,8 +18,11 @@ namespace mbgl {
class Color;
class PaintParameters;
class LayerTweaker;
enum class RenderPass : uint8_t;
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
namespace gfx {
class ColorMode;
@@ -234,6 +237,10 @@ public:
/// Get drawable user-defined type
size_t getType() const { return type; }
/// Associate the drawable with a layer tweaker. This is used to manage the lifetime of the tweaker.
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
protected:
bool enabled = true;
bool enableColor = true;
@@ -257,6 +264,7 @@ protected:
Textures textures;
std::vector<DrawableTweakerPtr> tweakers;
LayerTweakerPtr layerTweaker;
std::size_t type = 0;
};

View File

@@ -145,6 +145,9 @@ public:
/// @param location A sampler location in the shader being used.
void setTexture(const gfx::Texture2DPtr&, int32_t location);
/// Direct access to the current texture set
const gfx::Drawable::Textures& getTextures() const { return textures; }
/// Add a tweaker to emitted drawable
void addTweaker(DrawableTweakerPtr value) { tweakers.emplace_back(std::move(value)); }
@@ -225,5 +228,7 @@ protected:
std::unique_ptr<Impl> impl;
};
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
} // namespace gfx
} // namespace mbgl

View File

@@ -13,6 +13,7 @@ namespace mbgl {
class LayerGroupBase;
class PaintParameters;
class RenderOrchestrator;
class RenderTree;
class TileLayerGroup;
using LayerGroupBasePtr = std::shared_ptr<LayerGroupBase>;
@@ -28,6 +29,7 @@ using UniqueDrawable = std::unique_ptr<Drawable>;
class LayerTweaker;
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
using LayerTweakerWeakPtr = std::weak_ptr<LayerTweaker>;
/**
A layer-like group of drawables, not a group of layers.
@@ -86,16 +88,16 @@ public:
/// @return The number of items removed
virtual std::size_t removeDrawablesIf(const std::function<bool(gfx::Drawable&)>&& f) = 0;
/// Attach a tweaker to be run on this layer group for each frame
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
/// Attach a tweaker to be run on this layer group for each frame.
/// Tweaker lifetime is controlled by the render layer and drawables, the layer group retains a weak reference.
void addLayerTweaker(const LayerTweakerPtr& tweaker) { layerTweakers.emplace_back(tweaker); }
/// Get the tweaker attached to this layer group
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
void runTweakers(const RenderTree&, PaintParameters&);
protected:
bool enabled = true;
int32_t layerIndex;
LayerTweakerPtr layerTweaker;
std::vector<LayerTweakerWeakPtr> layerTweakers;
std::string name;
};

View File

@@ -9,6 +9,7 @@
namespace mbgl {
namespace gfx {
class Drawable;
class UniformBuffer;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
} // namespace gfx
@@ -45,17 +46,21 @@ public:
/// Build the common expression inupts UBO
static shaders::ExpressionInputsUBO buildExpressionUBO(double zoom, uint64_t frameCount);
/// @brief Set the collection of attribute names which will be provided at uniform values rather than per-vertex
/// attributes.
/// @details These values should not have "a_" prefixes, as produced by `readDataDrivenPaintProperties`.
void setPropertiesAsUniforms(std::vector<std::string>);
/// @brief Check whether a property name exists within the previously set collection.
/// @details The string value provided is expected to have the "a_" prefix, as defined in the shader classes.
bool hasPropertyAsUniform(std::string_view) const;
shaders::AttributeSource getAttributeSource(const std::string_view& attribName) const;
#endif // MLN_RENDER_BACKEND_METAL
/// @brief Set the collection of attribute names which will be provided at uniform values rather than per-vertex
/// attributes.
/// @details These values should not have "a_" prefixes, as produced by `readDataDrivenPaintProperties`.
#if MLN_RENDER_BACKEND_OPENGL
void setPropertiesAsUniforms(const std::vector<std::string>&) {}
#else
void setPropertiesAsUniforms(std::vector<std::string>);
#endif
void enableOverdrawInspector(bool);
virtual void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) = 0;
@@ -63,6 +68,9 @@ public:
void updateProperties(Immutable<style::LayerProperties>);
protected:
/// Determine whether this tweaker should apply to the given drawable
bool checkTweakDrawable(const gfx::Drawable&) const;
/// Calculate matrices for this tile.
/// @param nearClipped If true, the near plane is moved further to enhance depth buffer precision.
/// @param inViewportPixelUnits If false, the translation is scaled based on the current zoom.
@@ -78,7 +86,6 @@ protected:
protected:
std::string id;
Immutable<style::LayerProperties> evaluatedProperties;
bool propertiesUpdated = true;
#if MLN_RENDER_BACKEND_METAL
// For Metal, whether a property is provided through attribtues or uniforms is specified in
@@ -86,7 +93,12 @@ protected:
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool propertiesChanged = true;
// Indicates that the evaluated properties have changed
bool propertiesUpdated = true;
// Indicates that the properties-as-uniforms has changed
bool permutationUpdated = true;
bool overdrawInspector = false;
};

View File

@@ -27,13 +27,18 @@ public:
: v(other.v) {} // buffer is not copied
IndexVectorBase(IndexVectorBase&& other)
: v(std::move(other.v)),
#if MLN_DRAWABLE_RENDERER
buffer(std::move(other.buffer)),
#endif // MLN_DRAWABLE_RENDERER
dirty(other.dirty),
released(other.released) {}
released(other.released) {
}
virtual ~IndexVectorBase() = default;
#if MLN_DRAWABLE_RENDERER
IndexBufferBase* getBuffer() const { return buffer.get(); }
void setBuffer(std::unique_ptr<IndexBufferBase>&& value) { buffer = std::move(value); }
#endif // MLN_DRAWABLE_RENDERER
bool getDirty() const { return dirty; }
void setDirty(bool value = true) { dirty = value; }
@@ -41,12 +46,14 @@ public:
bool isReleased() const { return released; }
void extend(std::size_t n, const uint16_t val) {
assert(!released);
v.resize(v.size() + n, val);
dirty = true;
}
uint16_t& at(std::size_t n) {
assert(n < v.size());
assert(!released);
dirty = true;
return v.at(n);
}
@@ -66,11 +73,14 @@ public:
v.clear();
}
/// Indicate that this shared index vector will no longer be updated.
void release() {
#if MLN_DRAWABLE_RENDERER
// If we've already created a buffer, we don't need the raw data any more.
if (buffer) {
clear();
v.clear();
}
#endif // MLN_DRAWABLE_RENDERER
released = true;
}
@@ -79,7 +89,9 @@ public:
const std::vector<uint16_t>& vector() const { return v; }
protected:
#if MLN_DRAWABLE_RENDERER
std::unique_ptr<IndexBufferBase> buffer;
#endif // MLN_DRAWABLE_RENDERER
bool dirty = true;
bool released = false;
};
@@ -94,6 +106,7 @@ public:
template <class... Args>
void emplace_back(Args&&... args) {
static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
assert(!released);
util::ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
}
};

View File

@@ -17,17 +17,23 @@ public:
VertexVectorBase() = default;
VertexVectorBase(const VertexVectorBase&) {} // buffer is not copied
VertexVectorBase(VertexVectorBase&& other)
: buffer(std::move(other.buffer)),
:
#if MLN_DRAWABLE_RENDERER
buffer(std::move(other.buffer)),
#endif // MLN_DRAWABLE_RENDERER
dirty(other.dirty),
released(other.released) {}
released(other.released) {
}
virtual ~VertexVectorBase() = default;
virtual const void* getRawData() const = 0;
virtual std::size_t getRawSize() const = 0;
virtual std::size_t getRawCount() const = 0;
#if MLN_DRAWABLE_RENDERER
VertexBufferBase* getBuffer() const { return buffer.get(); }
void setBuffer(std::unique_ptr<VertexBufferBase>&& value) { buffer = std::move(value); }
#endif // MLN_DRAWABLE_RENDERER
bool getDirty() const { return dirty; }
void setDirty(bool value = true) { dirty = value; }
@@ -35,7 +41,9 @@ public:
bool isReleased() const { return released; }
protected:
#if MLN_DRAWABLE_RENDERER
std::unique_ptr<VertexBufferBase> buffer;
#endif // MLN_DRAWABLE_RENDERER
bool dirty = true;
bool released = false;
};
@@ -57,16 +65,20 @@ public:
template <typename Arg>
void emplace_back(Arg&& vertex) {
assert(!released);
v.emplace_back(std::forward<Arg>(vertex));
dirty = true;
}
void extend(std::size_t n, const Vertex& val) {
assert(!released);
v.resize(v.size() + n, val);
dirty = true;
}
Vertex& at(std::size_t n) {
assert(n < v.size());
assert(!released);
dirty = true;
return v.at(n);
}
@@ -86,11 +98,14 @@ public:
v.clear();
}
/// Indicate that this shared vertex vector instance will no longer be updated.
void release() {
#if MLN_DRAWABLE_RENDERER
// If we've already created a buffer, we don't need the raw data any more.
if (buffer) {
clear();
v.clear();
}
#endif // MLN_DRAWABLE_RENDERER
released = true;
}

View File

@@ -122,9 +122,11 @@ void DrawableGL::bindUniformBuffers() const {
const auto& uniformBuffer = getUniformBuffers().get(element.first);
if (!uniformBuffer) {
using namespace std::string_literals;
const auto tileID = getTileID() ? util::toString(*getTileID()) : "<no tile>";
Log::Error(Event::General,
"DrawableGL::bindUniformBuffers: UBO "s + std::string(StringIndexer::get(element.first)) +
" not found. skipping.");
"bindUniformBuffers: UBO "s + std::string(StringIndexer::get(element.first)) +
" not found for " + util::toString(getID()) + " / " + getName() + " / " + tileID +
". skipping.");
assert(false);
continue;
}

View File

@@ -43,6 +43,7 @@ void DrawableGLBuilder::init() {
impl->buildIndexes.clear();
impl->segments.clear();
impl->vertices.clear();
textures.clear();
}
} // namespace gl

View File

@@ -103,7 +103,8 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
#if !defined(NDEBUG)
std::string label_tile;
if (const auto& tileID = drawable.getTileID()) {
label_tile = drawable.getName() + "/" + util::toString(*tileID);
label_tile = util::toString(drawable.getID().id()) + "/" + drawable.getName() + "/" +
util::toString(*tileID);
}
const auto labelPtr = (label_tile.empty() ? drawable.getName() : label_tile).c_str();
const auto debugGroupTile = parameters.encoder->createDebugGroup(labelPtr);

View File

@@ -377,9 +377,11 @@ void Drawable::bindUniformBuffers(const RenderPass& renderPass) const {
const auto& uniformBuffer = getUniformBuffers().get(element.first);
if (!uniformBuffer) {
using namespace std::string_literals;
const auto tileID = getTileID() ? util::toString(*getTileID()) : "<no tile>";
const auto tileLabel = util::toString(getID()) + "/" + getName() + "/" + tileID;
Log::Error(Event::General,
"Drawable::bindUniformBuffers: UBO "s + StringIndexer::get(element.first) +
" not found. skipping.");
"bindUniformBuffers: UBO "s + StringIndexer::get(element.first) + " not found on " +
tileLabel + ". skipping.");
assert(false);
continue;
}
@@ -518,7 +520,9 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
auto& context = static_cast<Context&>(contextBase);
constexpr auto usage = gfx::BufferUsageType::StaticDraw;
if (!impl->indexes || !impl->indexes->bytes()) {
// We need either raw index data or a buffer already created from them.
// We can have a buffer and no indexes, but only if it's not marked dirty.
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || impl->indexes->getDirty()))) {
assert(!"Missing index data");
return;
}

View File

@@ -38,11 +38,13 @@ void DrawableBuilder::init() {
if (!impl->sharedIndexes && !impl->buildIndexes.empty()) {
impl->sharedIndexes = std::make_shared<gfx::IndexVectorBase>(std::move(impl->buildIndexes));
}
assert(impl->sharedIndexes && impl->sharedIndexes->elements());
drawable.setIndexData(std::move(impl->sharedIndexes), std::move(impl->segments));
impl->buildIndexes.clear();
impl->segments.clear();
impl->vertices.clear();
textures.clear();
}
} // namespace mtl

View File

@@ -13,7 +13,10 @@ RasterBucket::RasterBucket(PremultipliedImage&& image_)
RasterBucket::RasterBucket(std::shared_ptr<PremultipliedImage> image_)
: image(std::move(image_)) {}
RasterBucket::~RasterBucket() = default;
RasterBucket::~RasterBucket() {
clear();
setImage({});
}
void RasterBucket::upload([[maybe_unused]] gfx::UploadPass& uploadPass) {
if (!hasData()) {
@@ -49,6 +52,7 @@ void RasterBucket::clear() {
void RasterBucket::setImage(std::shared_ptr<PremultipliedImage> image_) {
image = std::move(image_);
texture = {};
texture2d.reset();
uploaded = false;
}

View File

@@ -9,10 +9,16 @@
#include <mbgl/util/image.hpp>
#include <mbgl/util/mat4.hpp>
#include <memory>
#include <optional>
namespace mbgl {
namespace gfx {
class Texture2D;
using Texture2DPtr = std::shared_ptr<Texture2D>;
} // namespace gfx
class RasterBucket final : public Bucket {
public:
RasterBucket(PremultipliedImage&&);
@@ -28,6 +34,7 @@ public:
std::shared_ptr<PremultipliedImage> image;
std::optional<gfx::Texture> texture;
gfx::Texture2DPtr texture2d;
TileMask mask{{0, 0, 0}};
// Bucket specific vertices are used for Image Sources only

View File

@@ -2,8 +2,10 @@
#include <mbgl/gfx/upload_pass.hpp>
#include <mbgl/gfx/drawable_tweaker.hpp>
#include <mbgl/renderer/layer_tweaker.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_orchestrator.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <set>
@@ -16,6 +18,17 @@ void LayerGroupBase::addDrawable(gfx::UniqueDrawable& drawable) {
}
}
void LayerGroupBase::runTweakers(const RenderTree& renderTree, PaintParameters& parameters) {
for (auto it = layerTweakers.begin(); it != layerTweakers.end();) {
if (auto tweaker = it->lock()) {
tweaker->execute(*this, renderTree, parameters);
++it;
} else {
it = layerTweakers.erase(it);
}
}
}
struct LayerGroup::Impl {
using DrawableCollection = std::set<gfx::UniqueDrawable, gfx::DrawableLessByPriority>;
DrawableCollection drawables;

View File

@@ -19,6 +19,12 @@ LayerTweaker::LayerTweaker(std::string id_, Immutable<style::LayerProperties> pr
: id(std::move(id_)),
evaluatedProperties(std::move(properties)) {}
bool LayerTweaker::checkTweakDrawable(const gfx::Drawable& drawable) const {
// Apply to a drawable if it references us, or if doesn't reference anything.
const auto& tweaker = drawable.getLayerTweaker();
return !tweaker || tweaker.get() == this;
}
mat4 LayerTweaker::getTileMatrix(const UnwrappedTileID& tileID,
const RenderTree& renderTree,
const TransformState& state,
@@ -60,12 +66,15 @@ shaders::ExpressionInputsUBO LayerTweaker::buildExpressionUBO(double zoom, uint6
0};
}
#if !MLN_RENDER_BACKEND_OPENGL
void LayerTweaker::setPropertiesAsUniforms(std::vector<std::string> props) {
if (props != propertiesAsUniforms) {
propertiesAsUniforms = std::move(props);
propertiesChanged = true;
permutationUpdated = true;
}
}
#endif
bool LayerTweaker::hasPropertyAsUniform(const std::string_view attrName) const {
// `attrName` is expected to have the "a_" prefix, while the values in `propertiesAsUniforms`
// do not. Search for the former within the latter without allocating temporary strings.
@@ -84,7 +93,7 @@ AttributeSource LayerTweaker::getAttributeSource(const std::string_view& attribN
void LayerTweaker::enableOverdrawInspector(bool value) {
if (overdrawInspector != value) {
overdrawInspector = value;
propertiesChanged = true;
permutationUpdated = true;
}
}

View File

@@ -54,6 +54,9 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const RenderTre
std::optional<uint32_t> samplerLocation{};
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
assert(drawable.getTileID());
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
// We assume that drawables don't change between pattern and non-pattern.
const auto& shader = drawable.getShader();

View File

@@ -61,7 +61,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = shaders::ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::Metal>;
if (propertiesChanged) {
if (permutationUpdated) {
const auto source = [this](const std::string_view& attrName) {
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
};
@@ -86,7 +86,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
propertiesChanged = false;
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
@@ -114,16 +114,16 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idCirclePaintParamsUBOName, paintParamsUniformBuffer);
uniforms.addOrReplace(idCircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
assert(!"Circles only render with tiles");
assert(drawable.getTileID() || !"Circles only render with tiles");
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idCirclePaintParamsUBOName, paintParamsUniformBuffer);
uniforms.addOrReplace(idCircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
const auto& translation = evaluated.get<CircleTranslate>();
const auto anchor = evaluated.get<CircleTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix

View File

@@ -50,7 +50,7 @@ void CollisionLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
if (!drawable.getTileID() || !drawable.getData() || !checkTweakDrawable(drawable)) {
return;
}

View File

@@ -77,7 +77,7 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
const auto zoom = parameters.state.getZoom();
if (propertiesChanged) {
if (permutationUpdated) {
const FillExtrusionPermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/getAttributeSource("a_color"), /*.expression=*/{}},
/* .base = */ {/*.source=*/getAttributeSource("a_base"), /*.expression=*/{}},
@@ -93,7 +93,7 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
} else {
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
propertiesChanged = false;
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
@@ -102,15 +102,15 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idFillExtrusionDrawablePropsUBOName, propsBuffer);
if (!drawable.getTileID()) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idFillExtrusionDrawablePropsUBOName, propsBuffer);
const auto& translation = evaluated.get<FillExtrusionTranslate>();
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix

View File

@@ -93,7 +93,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !fillPermutationUniformBuffer) {
if (permutationUpdated || !fillPermutationUniformBuffer) {
const FillPermutationUBO permutationUBO = {
/* .color = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
@@ -132,7 +132,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !fillOutlinePermutationUniformBuffer) {
if (permutationUpdated || !fillOutlinePermutationUniformBuffer) {
const FillOutlinePermutationUBO permutationUBO = {
/* .outline_color = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
/* .opacity = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
@@ -173,7 +173,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !fillPatternPermutationUniformBuffer) {
if (permutationUpdated || !fillPatternPermutationUniformBuffer) {
const FillPatternPermutationUBO permutationUBO = {
/* .pattern_from = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
@@ -212,7 +212,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = ShaderSource<BuiltIn::FillOutlinePatternShader, gfx::Backend::Type::Metal>;
if (propertiesChanged || !fillOutlinePermutationUniformBuffer) {
if (permutationUpdated || !fillOutlinePatternPermutationUniformBuffer) {
const FillOutlinePatternPermutationUBO permutationUBO = {
/* .pattern_from = */ {/*.source=*/source(ShaderClass::attributes[1].name), /*.expression=*/{}},
/* .pattern_to = */ {/*.source=*/source(ShaderClass::attributes[2].name), /*.expression=*/{}},
@@ -255,6 +255,10 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
// auto& drawableType = drawable.getShader()->typeName();
@@ -287,9 +291,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
}
}
}
if (!drawable.getTileID()) {
return;
}
if (uniforms.get(idFillInterpolateUBOName)) {
UpdateFillUniformBuffers();
@@ -361,7 +362,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif // MLN_RENDER_BACKEND_METAL
});
propertiesChanged = false;
permutationUpdated = false;
}
} // namespace mbgl

View File

@@ -44,7 +44,7 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using ShaderClass = shaders::ShaderSource<BuiltIn::HeatmapShader, gfx::Backend::Type::Metal>;
if (propertiesChanged) {
if (permutationUpdated) {
const auto source = [this](const std::string_view& attrName) {
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
};
@@ -66,7 +66,7 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
propertiesChanged = false;
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
@@ -85,13 +85,15 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.addOrReplace(idHeatmapEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(tileID,

View File

@@ -33,6 +33,10 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!checkTweakDrawable(drawable)) {
return;
}
const auto& size = parameters.staticData.backendSize;
mat4 viewportMat;
matrix::ortho(viewportMat, 0, size.width, size.height, 0, -1, 1);

View File

@@ -55,12 +55,14 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup,
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
drawable.mutableUniformBuffers().addOrReplace(idHillshadeEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
if (!drawable.getTileID()) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
drawable.mutableUniformBuffers().addOrReplace(idHillshadeEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
const auto matrix = getTileMatrix(
tileID, renderTree, parameters.state, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, true);
HillshadeDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),

View File

@@ -42,7 +42,7 @@ void HillshadePrepareLayerTweaker::execute(LayerGroupBase& layerGroup,
#endif
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
if (!drawable.getTileID() || !drawable.getData() || !checkTweakDrawable(drawable)) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
@@ -52,7 +52,7 @@ void HillshadePrepareLayerTweaker::execute(LayerGroupBase& layerGroup,
matrix::ortho(matrix, 0, util::EXTENT, -util::EXTENT, 0, -1, 1);
matrix::translate(matrix, matrix, 0, -util::EXTENT, 0);
HillshadePrepareDrawableUBO drawableUBO = {
const HillshadePrepareDrawableUBO drawableUBO = {
/* .matrix = */ util::cast<float>(matrix),
/* .unpack = */ getUnpackVector(drawableData.encoding),
/* .dimension = */ {static_cast<float>(drawableData.stride), static_cast<float>(drawableData.stride)},

View File

@@ -113,7 +113,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
#if MLN_RENDER_BACKEND_METAL
using LineShaderClass = shaders::ShaderSource<BuiltIn::LineShader, gfx::Backend::Type::Metal>;
if (propertiesChanged) {
if (permutationUpdated) {
const auto source = [this](const std::string_view& attrName) {
return hasPropertyAsUniform(attrName) ? AttributeSource::Constant : AttributeSource::PerVertex;
};
@@ -139,7 +139,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
} else {
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
propertiesChanged = false;
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
@@ -149,7 +149,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
const auto shader = drawable.getShader();
if (!drawable.getTileID() || !shader) {
if (!drawable.getTileID() || !shader || !checkTweakDrawable(drawable)) {
return;
}

View File

@@ -25,6 +25,10 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!checkTweakDrawable(drawable)) {
return;
}
const auto spinWeights = [](float spin) -> std::array<float, 4> {
spin = util::deg2radf(spin);
const float s = std::sin(spin);

View File

@@ -3,7 +3,6 @@
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/pattern_atlas.hpp>
@@ -67,7 +66,8 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif
}
@@ -250,12 +250,18 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<BackgroundLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
if (!hasPattern && !plainShader) {
plainShader = context.getGenericShader(shaders, std::string(BackgroundPlainShaderName));
}
@@ -312,6 +318,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(drawPasses, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -93,7 +93,10 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -276,19 +279,6 @@ static const StringIdentity idVertexAttribName = StringIndexer::get("a_pos");
using namespace shaders;
#if MLN_DRAWABLE_RENDERER
void RenderCircleLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -305,12 +295,19 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<CircleLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!circleShaderGroup) {
circleShaderGroup = shaders.getShaderGroup(CircleShaderGroupName);
}
@@ -319,14 +316,6 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
std::unique_ptr<gfx::DrawableBuilder> circleBuilder;
constexpr auto renderPass = RenderPass::Translucent;
@@ -375,6 +364,11 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
// If there are already drawables for this tile, update their UBOs and move on to the next tile.
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.createOrUpdate(idCircleInterpolateUBOName, &interpolateUBO, context);
};
@@ -385,29 +379,26 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
gfx::VertexAttributeArray circleVertexAttrs;
auto propertiesAsUniforms_ = circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
CircleRadius,
CircleBlur,
CircleOpacity,
CircleStrokeColor,
CircleStrokeWidth,
CircleStrokeOpacity>(
auto propertiesAsUniforms = circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
CircleRadius,
CircleBlur,
CircleOpacity,
CircleStrokeColor,
CircleStrokeWidth,
CircleStrokeOpacity>(
paintPropertyBinders, evaluated);
if (!circleShaderGroup) {
continue;
}
const auto circleShader = circleShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
const auto circleShader = circleShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!circleShader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
#endif // MLN_RENDER_BACKEND_METAL
if (const auto& attr = circleVertexAttrs.add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
@@ -434,6 +425,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : circleBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.addOrReplace(idCircleInterpolateUBOName, interpBuffer);

View File

@@ -49,10 +49,6 @@ private:
void render(PaintParameters&) override;
#endif // MLN_LEGACY_RENDERER
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
private:
// Paint properties
style::CirclePaintProperties::Unevaluated unevaluated;
@@ -64,13 +60,6 @@ private:
#if MLN_DRAWABLE_RENDERER
gfx::ShaderGroupPtr circleShaderGroup;
CircleLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -26,6 +26,7 @@
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#endif // MLN_DRAWABLE_RENDERER
@@ -75,7 +76,8 @@ void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& para
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -275,7 +277,7 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(const GeometryCoordinates&
void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const std::shared_ptr<UpdateParameters>& updateParameters,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -286,11 +288,19 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
}
if (!layerTweaker) {
layerTweaker = std::make_shared<FillExtrusionLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillExtrusionGroup) {
fillExtrusionGroup = shaders.getShaderGroup("FillExtrusionShader");
}
@@ -388,6 +398,11 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
if (tileLayerGroup->getDrawableCount(drawPass, tileID) > 0) {
// Just update the drawables we already created
tileLayerGroup->visitDrawables(drawPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
uniforms.createOrUpdate(
FillExtrusionLayerTweaker::idFillExtrusionTilePropsUBOName, &tilePropsUBO, context);
@@ -398,20 +413,25 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
}
gfx::VertexAttributeArray vertexAttrs;
const auto uniformProps = vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders, evaluated);
const auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders,
evaluated);
if (!shaderGroup) {
continue;
}
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, uniformProps));
shaderGroup->getOrCreateShader(context, propertiesAsUniforms));
if (!shader) {
continue;
}
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
// The non-pattern path in `render()` only uses two-pass rendering if there's translucency.
// The pattern path always uses two passes.
const auto doDepthPass = (!opaque || hasPattern);
@@ -492,6 +512,9 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
colorBuilder->setVertexAttributes(std::move(vertexAttrs));
const auto finish = [&](gfx::DrawableBuilder& builder) {
if (!bucket.sharedTriangles->elements()) {
return;
}
builder.setSegments(gfx::Triangles(),
bucket.sharedTriangles,
bucket.triangleSegments.data(),
@@ -501,6 +524,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(

View File

@@ -104,9 +104,9 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
layerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties));
auto newTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
updateLayerTweaker();
#endif
}
@@ -308,17 +308,6 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
#if MLN_DRAWABLE_RENDERER
void RenderFillLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -332,24 +321,22 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->setLayerTweaker(std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties));
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!fillShaderGroup) {
fillShaderGroup = shaders.getShaderGroup(std::string(FillShaderName));
}
@@ -373,7 +360,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
std::unique_ptr<gfx::DrawableBuilder> outlinePatternBuilder;
const auto layerPrefix = getID() + "/";
const auto renderPass = RenderPass::Translucent;
constexpr auto renderPass = RenderPass::Translucent;
const auto commonInit = [&](gfx::DrawableBuilder& builder) {
builder.setCullFaceMode(gfx::CullFaceMode::disabled());
@@ -383,10 +370,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
stats.drawablesRemoved += tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
const auto& tileID = drawable.getTileID();
if (tileID && !hasRenderTile(*tileID)) {
return true;
}
return false;
return tileID && !hasRenderTile(*tileID);
});
for (const RenderTile& tile : *renderTiles) {
@@ -519,10 +503,14 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// `Fill*Program` all use `style::FillPaintProperties`
gfx::VertexAttributeArray vertexAttrs;
const auto propertiesAsUniforms_ =
const auto propertiesAsUniforms =
vertexAttrs.readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(binders,
evaluated);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
const auto vertexCount = bucket.vertices.elements();
if (const auto& attr = vertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
@@ -534,6 +522,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// If we already have drawables for this tile, update them.
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
if (uniforms.get(FillLayerTweaker::idFillInterpolateUBOName)) {
uniforms.createOrUpdate(FillLayerTweaker::idFillInterpolateUBOName, &getFillInterpolateUBO(), context);
@@ -566,19 +559,12 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto fillShader = std::static_pointer_cast<gfx::ShaderProgramBase>(
fillShaderGroup->getOrCreateShader(context, propertiesAsUniforms_));
fillShaderGroup->getOrCreateShader(context, propertiesAsUniforms));
const auto outlineShader = doOutline
? std::static_pointer_cast<gfx::ShaderProgramBase>(
outlineShaderGroup->getOrCreateShader(context, propertiesAsUniforms_))
outlineShaderGroup->getOrCreateShader(context, propertiesAsUniforms))
: nullptr;
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (!fillBuilder && fillShader) {
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill")) {
commonInit(*builder);
@@ -610,6 +596,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(interpolateUBONameId, &interpolateUBO, context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
@@ -653,19 +641,12 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
const auto fillShader = std::static_pointer_cast<gfx::ShaderProgramBase>(
patternShaderGroup->getOrCreateShader(context, propertiesAsUniforms_));
patternShaderGroup->getOrCreateShader(context, propertiesAsUniforms));
const auto outlineShader = doOutline ? std::static_pointer_cast<gfx::ShaderProgramBase>(
outlinePatternShaderGroup->getOrCreateShader(
context, propertiesAsUniforms_))
context, propertiesAsUniforms))
: nullptr;
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (!patternBuilder) {
if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-pattern")) {
commonInit(*builder);
@@ -708,6 +689,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
uniforms.createOrUpdate(interpolateNameId, &interpolateUBO, context);
uniforms.createOrUpdate(tileUBONameId, &tileUBO, context);

View File

@@ -46,10 +46,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
float,
@@ -73,13 +69,6 @@ private:
gfx::ShaderGroupPtr outlineShaderGroup;
gfx::ShaderGroupPtr patternShaderGroup;
gfx::ShaderGroupPtr outlinePatternShaderGroup;
FillLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -70,8 +70,17 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
updateLayerTextureTweaker();
if (layerGroup) {
auto newTextureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(textureTweaker, std::move(newTextureTweaker), {layerGroup});
}
if (renderTarget) {
if (auto tileLayerGroup = renderTarget->getLayerGroup(0)) {
auto newTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {std::move(tileLayerGroup)});
}
}
#endif
}
@@ -247,17 +256,24 @@ void RenderHeatmapLayer::markLayerRenderable(bool willRender, UniqueChangeReques
activateRenderTarget(renderTarget, willRender, changes);
}
void RenderHeatmapLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
auto* tileLayerGroup = static_cast<TileLayerGroup*>(renderTarget->getLayerGroup(0).get());
stats.drawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size();
std::size_t RenderHeatmapLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
if (auto* tileLayerGroup = static_cast<TileLayerGroup*>(renderTarget->getLayerGroup(0).get())) {
const auto count = tileLayerGroup->removeDrawables(renderPass, tileID).size();
stats.drawablesRemoved += count;
return count;
}
return 0;
}
void RenderHeatmapLayer::removeAllDrawables() {
RenderLayer::removeAllDrawables();
std::size_t RenderHeatmapLayer::removeAllDrawables() {
auto removed = RenderLayer::removeAllDrawables();
if (renderTarget) {
stats.drawablesRemoved += renderTarget->getLayerGroup(0)->getDrawableCount();
const auto count = renderTarget->getLayerGroup(0)->getDrawableCount();
removed += count;
stats.drawablesRemoved += count;
renderTarget->getLayerGroup(0)->clearDrawables();
}
return removed;
}
namespace {
@@ -273,27 +289,6 @@ static const StringIdentity idTexColorRampName = StringIndexer::get("u_color_ram
using namespace shaders;
#if MLN_DRAWABLE_RENDERER
void RenderHeatmapLayer::updateLayerTweaker() {
if (renderTarget) {
tweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
renderTarget->getLayerGroup(0)->setLayerTweaker(tweaker);
}
}
void RenderHeatmapLayer::updateLayerTextureTweaker() {
if (layerGroup) {
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
textureTweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(textureTweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
@@ -324,7 +319,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
return;
}
renderTarget->addLayerGroup(tileLayerGroup, /*replace=*/true);
updateLayerTweaker();
textureTweaker.reset();
}
if (renderTarget->getTexture()->getSize() != size) {
@@ -341,14 +336,11 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
textureTweaker->enableOverdrawInspector(overdrawInspector);
}
if (!layerTweaker) {
layerTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
tileLayerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
std::unique_ptr<gfx::DrawableBuilder> heatmapBuilder;
constexpr auto renderPass = RenderPass::Translucent;
@@ -383,40 +375,52 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
setRenderTileBucketID(tileID, bucket.getID());
const float zoom = static_cast<float>(state.getZoom());
const HeatmapInterpolateUBO interpolateUBO = {
/* .weight_t = */ std::get<0>(paintPropertyBinders.get<HeatmapWeight>()->interpolationFactor(zoom)),
/* .radius_t = */ std::get<0>(paintPropertyBinders.get<HeatmapRadius>()->interpolationFactor(zoom)),
/* .padding = */ {0}};
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
drawable.mutableUniformBuffers().createOrUpdate(idHeatmapInterpolateUBOName, &interpolateUBO, context);
});
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
continue;
}
gfx::UniformBufferPtr interpolateBuffer;
const auto getInterpolateBuffer = [&]() {
if (!interpolateBuffer) {
const HeatmapInterpolateUBO interpolateUBO = {
/* .weight_t = */ std::get<0>(paintPropertyBinders.get<HeatmapWeight>()->interpolationFactor(zoom)),
/* .radius_t = */ std::get<0>(paintPropertyBinders.get<HeatmapRadius>()->interpolationFactor(zoom)),
/* .padding = */ {0}};
interpolateBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
}
return interpolateBuffer;
};
gfx::VertexAttributeArray heatmapVertexAttrs;
const auto propertiesAsUniforms_ =
const auto propertiesAsUniforms =
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(paintPropertyBinders,
evaluated);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
if (!heatmapShaderGroup) {
const auto updatedCount = tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
// We assume vertex attributes don't change, and so don't update them to avoid re-uploading
// drawable.setVertexAttributes(heatmapVertexAttrs);
auto& uniforms = drawable.mutableUniformBuffers();
if (auto buffer = getInterpolateBuffer()) {
uniforms.addOrReplace(idHeatmapInterpolateUBOName, std::move(buffer));
}
});
if (updatedCount > 0) {
continue;
}
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!heatmapShader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
if (const auto& attr = heatmapVertexAttrs.add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(HeatmapLayoutVertex, a1),
@@ -441,7 +445,13 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : heatmapBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->mutableUniformBuffers().createOrUpdate(idHeatmapInterpolateUBOName, &interpolateUBO, context);
drawable->setLayerTweaker(layerTweaker);
auto& uniforms = drawable->mutableUniformBuffers();
if (auto buffer = getInterpolateBuffer()) {
uniforms.addOrReplace(idHeatmapInterpolateUBOName, std::move(buffer));
}
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
@@ -450,13 +460,20 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
// Set up texture layer group
if (!layerGroup) {
auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID());
if (!layerGroup_) {
if (auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID())) {
if (textureTweaker) {
layerGroup_->addLayerTweaker(textureTweaker);
}
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTextureTweaker();
}
if (!textureTweaker) {
textureTweaker = std::make_shared<HeatmapTextureLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(textureTweaker);
}
textureTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!heatmapTextureShader) {
heatmapTextureShader = context.getGenericShader(shaders, HeatmapTextureShaderGroupName);
@@ -467,6 +484,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
auto* textureLayerGroup = static_cast<LayerGroup*>(layerGroup.get());
// TODO: Don't rebuild drawables every time
textureLayerGroup->clearDrawables();
std::unique_ptr<gfx::DrawableBuilder> heatmapTextureBuilder;
@@ -516,6 +534,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
heatmapTextureBuilder->flush();
for (auto& drawable : heatmapTextureBuilder->clearDrawables()) {
drawable->setLayerTweaker(textureTweaker);
textureLayerGroup->addDrawable(std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -47,11 +47,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
void updateLayerTextureTweaker();
#endif // MLN_DRAWABLE_RENDERER
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
float,
@@ -63,10 +58,12 @@ private:
#if MLN_DRAWABLE_RENDERER
/// Remove all drawables for the tile from the layer group
void removeTile(RenderPass, const OverscaledTileID&) override;
/// @return The number of drawables actually removed.
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
void removeAllDrawables() override;
/// @return The number of drawables actually removed.
std::size_t removeAllDrawables() override;
#endif
// Paint properties
@@ -90,13 +87,9 @@ private:
using TextureVertexVector = gfx::VertexVector<HeatmapTextureLayoutVertex>;
std::shared_ptr<TextureVertexVector> sharedTextureVertices;
HeatmapLayerTweakerPtr tweaker;
HeatmapTextureLayerTweakerPtr textureTweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
// This is the layer tweaker for applying the off-screen texture to the framebuffer.
// The inherited layer tweaker is for applying tiles to the off-screen texture.
LayerTweakerPtr textureTweaker;
#endif
};

View File

@@ -73,7 +73,26 @@ void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& paramete
properties->renderPasses = mbgl::underlying_type(passes);
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
if (!activatedRenderTargets.empty()) {
auto newTweaker2 = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
std::vector<LayerGroupBasePtr> groups;
for (const auto& target : activatedRenderTargets) {
if (const auto& group = target->getLayerGroup(0)) {
groups.push_back(group);
}
}
if (groups.empty()) {
prepareLayerTweaker = newTweaker2;
} else {
replaceTweaker(prepareLayerTweaker, std::move(newTweaker2), groups);
}
}
#endif
}
@@ -284,16 +303,6 @@ static const StringIdentity idPosAttribName = StringIndexer::get("a_pos");
static const StringIdentity idTexturePosAttribName = StringIndexer::get("a_texture_pos");
static const StringIdentity idTexImageName = StringIndexer::get("u_image");
#if MLN_DRAWABLE_RENDERER
void RenderHillshadeLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
#endif // MLN_DRAWABLE_RENDERER
void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
[[maybe_unused]] const TransformState& state,
@@ -309,16 +318,21 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
if (!layerGroup_) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
setLayerGroup(std::move(layerGroup_), changes);
} else {
return;
}
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<HillshadeLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!hillshadePrepareShader) {
hillshadePrepareShader = context.getGenericShader(shaders, HillshadePrepareShaderGroupName);
}
@@ -330,12 +344,8 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
if (!hillshadeImageLocation) {
hillshadeImageLocation = hillshadeShader->getSamplerLocation(idTexImageName);
}
auto renderPass = RenderPass::Translucent;
@@ -389,11 +399,13 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
if (!singleTileLayerGroup) {
return;
}
const auto prepareTweaker = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
prepareTweaker->enableOverdrawInspector(overdrawInspector);
singleTileLayerGroup->setLayerTweaker(prepareTweaker);
renderTarget->addLayerGroup(singleTileLayerGroup, /*replace=*/true);
if (!prepareLayerTweaker) {
prepareLayerTweaker = std::make_shared<HillshadePrepareLayerTweaker>(getID(), evaluatedProperties);
}
singleTileLayerGroup->addLayerTweaker(prepareLayerTweaker);
gfx::VertexAttributeArray hillshadePrepareVertexAttrs;
if (const auto& attr = hillshadePrepareVertexAttrs.add(idPosAttribName)) {
@@ -437,6 +449,7 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : hillshadePrepareBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(prepareLayerTweaker);
drawable->setData(std::make_unique<gfx::HillshadePrepareDrawableData>(
bucket.getDEMData().stride, bucket.getDEMData().encoding, maxzoom));
singleTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
@@ -474,31 +487,38 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadeBuilder = context.createDrawableBuilder("hillshade");
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
drawable.setVertexAttributes(std::move(hillshadeVertexAttrs));
drawable.setVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
auto updateExisting = [&](gfx::Drawable& drawable) {
// Only current drawables are updated, ones produced for
// a previous style retain the attribute values for that style.
if (drawable.getLayerTweaker() != layerTweaker) {
return;
}
std::vector<std::unique_ptr<gfx::Drawable::DrawSegment>> drawSegments;
for (std::size_t i = 0; i < segments->size(); ++i) {
const auto& seg = segments->data()[i];
auto segCopy = SegmentBase{
// no copy constructor
seg.vertexOffset,
seg.indexOffset,
seg.vertexLength,
seg.indexLength,
seg.sortKey,
};
drawSegments.emplace_back(hillshadeBuilder->createSegment(gfx::Triangles(), std::move(segCopy)));
}
drawable.setIndexData(indices->vector(), std::move(drawSegments));
drawable.setVertexAttributes(std::move(hillshadeVertexAttrs));
drawable.setVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
auto imageLocation = hillshadeShader->getSamplerLocation(idTexImageName);
if (imageLocation.has_value()) {
drawable.setTexture(bucket.renderTarget->getTexture(), imageLocation.value());
}
});
// Rebuild segments, since they're not shared.
std::vector<std::unique_ptr<gfx::Drawable::DrawSegment>> drawSegments;
drawSegments.reserve(segments->size());
for (std::size_t i = 0; i < segments->size(); ++i) {
const auto& seg = segments->data()[i];
auto segCopy = SegmentBase{
// no copy constructor
seg.vertexOffset,
seg.indexOffset,
seg.vertexLength,
seg.indexLength,
seg.sortKey,
};
drawSegments.emplace_back(hillshadeBuilder->createSegment(gfx::Triangles(), std::move(segCopy)));
}
drawable.setIndexData(indices->vector(), std::move(drawSegments));
if (hillshadeImageLocation) {
drawable.setTexture(bucket.renderTarget->getTexture(), *hillshadeImageLocation);
}
};
if (0 < tileLayerGroup->visitDrawables(renderPass, tileID, std::move(updateExisting))) {
continue;
}
@@ -512,15 +532,16 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadeBuilder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
hillshadeBuilder->setSegments(gfx::Triangles(), indices->vector(), segments->data(), segments->size());
auto imageLocation = hillshadeShader->getSamplerLocation(idTexImageName);
if (imageLocation.has_value()) {
hillshadeBuilder->setTexture(bucket.renderTarget->getTexture(), imageLocation.value());
if (hillshadeImageLocation) {
hillshadeBuilder->setTexture(bucket.renderTarget->getTexture(), *hillshadeImageLocation);
}
hillshadeBuilder->flush();
for (auto& drawable : hillshadeBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -70,13 +70,13 @@ private:
#if MLN_DRAWABLE_RENDERER
gfx::ShaderProgramBasePtr hillshadePrepareShader;
gfx::ShaderProgramBasePtr hillshadeShader;
std::optional<int> hillshadeImageLocation;
std::vector<RenderTargetPtr> activatedRenderTargets;
using HillshadeVertexVector = gfx::VertexVector<HillshadeLayoutVertex>;
std::shared_ptr<HillshadeVertexVector> staticDataSharedVertices;
HillshadeLayerTweakerPtr tweaker;
bool overdrawInspector = false;
LayerTweakerPtr prepareLayerTweaker;
#endif
};

View File

@@ -21,16 +21,6 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/math.hpp>
#if MLN_DRAWABLE_RENDERER
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/line_layer_tweaker.hpp>
#include <mbgl/gfx/line_drawable_data.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/string_indexer.hpp>
#endif
#if MLN_DRAWABLE_RENDERER
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
#include <mbgl/gfx/drawable_builder.hpp>
@@ -40,6 +30,7 @@
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/line_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/string_indexer.hpp>
#endif
namespace mbgl {
@@ -90,7 +81,10 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
}
#endif
}
@@ -364,16 +358,6 @@ static const StringIdentity idLineSDFInterpolationUBOName = StringIndexer::get("
/// Evaluated properties that depend on the tile
static const StringIdentity idLinePatternTilePropertiesUBOName = StringIndexer::get("LinePatternTilePropertiesUBO");
void RenderLineLayer::updateLayerTweaker() {
if (layerGroup) {
tweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
tweaker->enableOverdrawInspector(overdrawInspector);
layerGroup->setLayerTweaker(tweaker);
}
}
static const StringIdentity idLineImageUniformName = StringIndexer::get("u_image");
@@ -390,23 +374,22 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
return;
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
}
}
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
} else {
return;
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
if (!layerTweaker) {
layerTweaker = std::make_shared<LineLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!lineShaderGroup) {
lineShaderGroup = shaders.getShaderGroup("LineShader");
}
@@ -486,6 +469,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
}
auto& bucket = static_cast<LineBucket&>(*renderData->bucket);
if (!bucket.sharedTriangles->elements()) {
removeTile(renderPass, tileID);
continue;
}
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
const auto& crossfade = getCrossfade<LineLayerProperties>(renderData->layerProperties);
@@ -546,6 +534,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// update existing drawables
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
const auto& shader = drawable.getShader();
const auto& shaderUniforms = shader->getUniformBlocks();
auto& drawableUniforms = drawable.mutableUniformBuffers();
@@ -581,29 +574,26 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
if (!evaluated.get<LineDasharray>().from.empty()) {
// dash array line (SDF)
gfx::VertexAttributeArray vertexAttrs;
auto propertiesAsUniforms_ = vertexAttrs.readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth,
LineFloorWidth>(paintPropertyBinders,
evaluated);
auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth,
LineFloorWidth>(paintPropertyBinders,
evaluated);
if (!lineSDFShaderGroup) {
continue;
}
auto shader = lineSDFShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
auto shader = lineSDFShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!shader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("lineSDF", std::move(shader));
@@ -618,6 +608,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::SDF));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->setData(std::make_unique<gfx::LineDrawableData>(cap));
drawable->mutableUniformBuffers().createOrUpdate(
idLineSDFInterpolationUBOName, &lineSDFInterpolationUBO, context);
@@ -629,28 +620,25 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// pattern line
gfx::VertexAttributeArray vertexAttrs;
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
auto propertiesAsUniforms_ = vertexAttrs.readDataDrivenPaintProperties<LineBlur,
LineOpacity,
LineOffset,
LineGapWidth,
LineWidth,
LinePattern>(paintPropertyBinders,
evaluated);
auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineBlur,
LineOpacity,
LineOffset,
LineGapWidth,
LineWidth,
LinePattern>(paintPropertyBinders,
evaluated);
if (!linePatternShaderGroup) {
continue;
}
auto shader = linePatternShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
auto shader = linePatternShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!shader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("linePattern", std::move(shader));
@@ -679,6 +667,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLinePatternInterpolationUBOName, &linePatternInterpolationUBO, context);
drawable->mutableUniformBuffers().createOrUpdate(
@@ -691,24 +680,21 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
} else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) {
// gradient line
gfx::VertexAttributeArray vertexAttrs;
auto propertiesAsUniforms_ =
auto propertiesAsUniforms =
vertexAttrs.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
paintPropertyBinders, evaluated);
if (!lineGradientShaderGroup) {
continue;
}
auto shader = lineGradientShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
auto shader = lineGradientShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!shader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("lineGradient", std::move(shader));
@@ -736,6 +722,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineGradientInterpolationUBOName, &lineGradientInterpolationUBO, context);
@@ -748,33 +735,30 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
} else {
// simple line
gfx::VertexAttributeArray vertexAttrs;
const auto propertiesAsUniforms_ = vertexAttrs.readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth>(
paintPropertyBinders, evaluated);
const auto propertiesAsUniforms = vertexAttrs.readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth>(paintPropertyBinders,
evaluated);
assert(6 == propertiesAsUniforms_.size());
assert(vertexAttrs.size() == (size_t)std::count_if(propertiesAsUniforms_.begin(),
propertiesAsUniforms_.end(),
assert(6 == propertiesAsUniforms.size());
assert(vertexAttrs.size() == (size_t)std::count_if(propertiesAsUniforms.begin(),
propertiesAsUniforms.end(),
[](const auto& s) { return s.empty(); }));
if (!lineShaderGroup) {
continue;
}
auto shader = lineShaderGroup->getOrCreateShader(context, propertiesAsUniforms_);
auto shader = lineShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!shader) {
continue;
}
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = std::move(propertiesAsUniforms_);
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(std::move(propertiesAsUniforms));
}
#endif // MLN_RENDER_BACKEND_METAL
auto builder = createLineBuilder("line", std::move(shader));
@@ -787,6 +771,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineInterpolationUBOName, &lineInterpolationUBO, context);

View File

@@ -58,9 +58,6 @@ private:
#if MLN_LEGACY_RENDERER
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif
bool queryIntersectsFeature(const GeometryCoordinates&,
const GeometryTileFeature&,
@@ -97,13 +94,6 @@ private:
gfx::ShaderGroupPtr linePatternShaderGroup;
gfx::DrawableTweakerPtr iconTweaker;
LineLayerTweakerPtr tweaker;
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
bool overdrawInspector = false;
#endif
};

View File

@@ -11,6 +11,7 @@
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/math/angles.hpp>
#include <mbgl/style/layers/raster_layer_impl.hpp>
#include <mbgl/util/logging.hpp>
#if MLN_DRAWABLE_RENDERER
#include <mbgl/renderer/layers/raster_layer_tweaker.hpp>
@@ -53,7 +54,10 @@ void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
updateLayerTweaker();
if (layerGroup) {
auto newTweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup, imageLayerGroup});
}
#endif
}
@@ -247,19 +251,6 @@ static const StringIdentity idTexturePosAttribName = StringIndexer::get("a_textu
static const StringIdentity idTexImage0Name = StringIndexer::get("u_image0");
static const StringIdentity idTexImage1Name = StringIndexer::get("u_image1");
void RenderRasterLayer::updateLayerTweaker() {
if (layerGroup || imageLayerGroup) {
tweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
tweaker->enableOverdrawInspector(overdrawInspector);
if (layerGroup) {
layerGroup->setLayerTweaker(tweaker);
}
if (imageLayerGroup) {
imageLayerGroup->setLayerTweaker(tweaker);
}
}
}
void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& /*state*/,
@@ -278,22 +269,28 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
return;
}
auto renderPass = RenderPass::Translucent;
constexpr auto renderPass = RenderPass::Translucent;
if (!rasterShader) {
rasterShader = context.getGenericShader(shaders, "RasterShader");
if (!rasterShader) {
return;
}
rasterSampler0 = rasterShader->getSamplerLocation(idTexImage0Name);
rasterSampler1 = rasterShader->getSamplerLocation(idTexImage1Name);
}
const bool overdraw = !!(updateParameters->debugOptions & MapDebugOptions::Overdraw);
if (overdrawInspector != overdraw) {
overdrawInspector = overdraw;
if (tweaker) {
tweaker->enableOverdrawInspector(overdrawInspector);
if (!layerTweaker) {
layerTweaker = std::make_shared<RasterLayerTweaker>(getID(), evaluatedProperties);
if (layerGroup) {
layerGroup->addLayerTweaker(layerTweaker);
}
if (imageLayerGroup) {
imageLayerGroup->addLayerTweaker(layerTweaker);
}
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
if (!staticDataVertices) {
staticDataVertices = std::make_shared<RasterVertexVector>(RenderStaticData::rasterVertices());
@@ -305,61 +302,65 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
staticDataSegments = std::make_shared<RasterSegmentVector>(RenderStaticData::rasterSegments());
}
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
RasterProgram::Binders paintAttributeData{evaluated, 0};
const gfx::TextureFilterType filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest
? gfx::TextureFilterType::Nearest
: gfx::TextureFilterType::Linear;
auto createBuilder = [&context, &renderPass, this]() -> std::unique_ptr<gfx::DrawableBuilder> {
std::unique_ptr<gfx::DrawableBuilder> builder{context.createDrawableBuilder("raster")};
const auto createBuilder = [&] {
auto builder = context.createDrawableBuilder("raster");
builder->setShader(rasterShader);
builder->setRenderPass(renderPass);
builder->setSubLayerIndex(0);
builder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
: gfx::DepthMaskType::ReadOnly);
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setColorMode(gfx::ColorMode::alphaBlended());
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setVertexAttrNameId(idPosAttribName);
return builder;
};
auto setTextures = [&context, &filter, this](std::unique_ptr<gfx::DrawableBuilder>& builder,
const RasterBucket& bucket) {
// textures
auto location0 = rasterShader->getSamplerLocation(idTexImage0Name);
if (location0.has_value()) {
std::shared_ptr<gfx::Texture2D> tex0 = context.createTexture2D();
tex0->setImage(bucket.image);
tex0->setSamplerConfiguration({filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
builder->setTexture(tex0, location0.value());
}
auto location1 = rasterShader->getSamplerLocation(idTexImage1Name);
if (location1.has_value()) {
std::shared_ptr<gfx::Texture2D> tex1 = context.createTexture2D();
tex1->setImage(bucket.image);
tex1->setSamplerConfiguration({filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
builder->setTexture(tex1, location1.value());
const auto setTextures = [&](gfx::UniqueDrawableBuilder& builder, RasterBucket& bucket) {
if (bucket.image && (rasterSampler0 || rasterSampler1)) {
if (!bucket.texture2d) {
if (auto tex = context.createTexture2D()) {
tex->setImage(bucket.image);
bucket.texture2d = std::move(tex);
}
}
if (bucket.texture2d) {
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
const bool nearest = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest;
const auto filter = nearest ? gfx::TextureFilterType::Nearest : gfx::TextureFilterType::Linear;
bucket.texture2d->setSamplerConfiguration(
{filter, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
if (rasterSampler0) {
builder->setTexture(bucket.texture2d, *rasterSampler0);
}
if (rasterSampler1) {
builder->setTexture(bucket.texture2d, *rasterSampler1);
}
}
}
};
auto buildVertexData = [this](std::unique_ptr<gfx::DrawableBuilder>& builder, const RasterBucket& bucket) {
RasterVertexVectorPtr vertices = staticDataVertices;
TriangleIndexVectorPtr indices = staticDataIndices;
const RasterSegmentVector* segments = staticDataSegments.get();
// Build vertex attributes and apply them to a drawable or a builder.
// Populates a drawable xor a drawable builder for creates and updates, respectively.
// Returns false if the drawable must be re-created.
const auto buildVertexData =
[this](const gfx::UniqueDrawableBuilder& builder, gfx::Drawable* drawable, const RasterBucket& bucket) {
// The bucket only fills in geometry for masked tiles,
// otherwise the standard tile extent geometry should be used.
const bool shared = (!bucket.sharedVertices->empty() && !bucket.sharedTriangles->empty() &&
!bucket.segments.empty());
const auto& vertices = shared ? bucket.sharedVertices : staticDataVertices;
const auto& indices = shared ? bucket.sharedTriangles : staticDataIndices;
const auto* segments = shared ? &bucket.segments : staticDataSegments.get();
if (!bucket.vertices.empty() && !bucket.indices.empty() && !bucket.segments.empty()) {
vertices = bucket.sharedVertices;
indices = bucket.sharedTriangles;
segments = &bucket.segments;
}
// The bucket may later add, remove, or change masking. In that case, the tile's
// shared data and segments are not updated, and it needs to be re-created.
if (drawable && (bucket.sharedVertices->getDirty() || bucket.sharedTriangles->getDirty())) {
return false;
}
// attributes
{
gfx::VertexAttributeArray vertexAttrs;
if (auto& attr = vertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a1),
@@ -376,109 +377,128 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::AttributeDataType::Short2);
}
builder->setVertexAttributes(std::move(vertexAttrs));
assert(!!drawable ^ !!builder);
if (drawable) {
drawable->setVertexAttributes(std::move(vertexAttrs));
} else if (builder) {
builder->setVertexAttributes(std::move(vertexAttrs));
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indices, segments->data(), segments->size());
}
return true;
};
gfx::UniqueDrawableBuilder builder;
if (imageData) {
// TODO: Can we avoid rebuilding drawables each time in this case as well?
if (imageLayerGroup) {
stats.drawablesRemoved += imageLayerGroup->clearDrawables();
}
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indices, segments->data(), segments->size());
};
auto buildDrawables = [&setTextures, &buildVertexData](std::unique_ptr<gfx::DrawableBuilder>& builder,
const RasterBucket& bucket) {
buildVertexData(builder, bucket);
setTextures(builder, bucket);
};
auto updateTileDrawables = [&](std::unique_ptr<gfx::DrawableBuilder>& builder,
auto* tileLayerGroup,
const auto& tileID,
const RasterBucket& bucket) {
// TODO: check for oportunity to skip
buildVertexData(builder, bucket);
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
for (auto& tex : drawable.getTextures()) {
builder->setTexture(tex.second, tex.first);
}
});
};
if (imageData) {
RasterBucket& bucket = *imageData->bucket;
if (!bucket.vertices.empty()) {
if (imageLayerGroup) {
stats.drawablesRemoved += imageLayerGroup->clearDrawables();
} else {
if (!imageLayerGroup) {
// Set up a layer group
imageLayerGroup = context.createLayerGroup(layerIndex, /*initialCapacity=*/64, getID());
imageLayerGroup->addLayerTweaker(layerTweaker);
activateLayerGroup(imageLayerGroup, isRenderable, changes);
updateLayerTweaker();
}
auto builder = createBuilder();
// Create a drawable for each transformation
// TODO: Share textures
builder = createBuilder();
for (const auto& matrix_ : imageData->matrices) {
buildDrawables(builder, bucket);
buildVertexData(builder, /*drawable=*/nullptr, bucket);
setTextures(builder, bucket);
// finish
builder->flush();
for (auto& drawable : builder->clearDrawables()) {
drawable->setData(std::make_unique<gfx::ImageDrawableData>(matrix_));
drawable->setLayerTweaker(layerTweaker);
imageLayerGroup->addDrawable(std::move(drawable));
++stats.drawablesAdded;
}
}
}
} else if (renderTiles) {
// Remove existing drawables that are no longer in the cover set
if (layerGroup) {
stats.drawablesRemoved += layerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
// Has this tile dropped out of the cover set?
return drawable.getTileID() && !hasRenderTile(*drawable.getTileID());
});
stats.drawablesRemoved += layerGroup->removeDrawablesIf(
[&](gfx::Drawable& drawable) { return drawable.getTileID() && !hasRenderTile(*drawable.getTileID()); });
} else {
// Set up a tile layer group
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
layerGroup_->addLayerTweaker(layerTweaker);
setLayerGroup(std::move(layerGroup_), changes);
updateLayerTweaker();
}
}
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
auto builder = createBuilder();
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
const auto* bucket_ = tile.getBucket(*baseImpl);
auto* bucket_ = tile.getBucket(*baseImpl);
if (!bucket_ || !bucket_->hasData()) {
removeTile(renderPass, tileID);
continue;
}
const auto& bucket = static_cast<const RasterBucket&>(*bucket_);
bool cleared = false;
auto& bucket = static_cast<RasterBucket&>(*bucket_);
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
// This tile was previously set up from a different bucket, drop and re-create any drawables for it.
// If the bucket data has changed, rebuild the drawables.
const bool bucketSharedData = (!bucket.vertices.empty() && !bucket.indices.empty() &&
!bucket.segments.empty());
const bool bucketDirty = bucketSharedData && (bucket.vertices.getDirty() || bucket.indices.getDirty());
if (bucketDirty) {
// Note, vertex/index dirty flags will be reset when those buffers are uploaded.
removeTile(renderPass, tileID);
cleared = true;
} else if (setRenderTileBucketID(tileID, bucket.getID())) {
// Bucket ID changed, we need to rebuild the drawables
removeTile(renderPass, tileID);
cleared = true;
}
setRenderTileBucketID(tileID, bucket.getID());
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
// re-create drawable geometry and pass texture
updateTileDrawables(builder, tileLayerGroup, tileID, bucket);
if (!cleared) {
// Update existing drawables
bool geometryChanged = false;
const auto updated = tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
gfx::UniqueDrawableBuilder none;
if (!geometryChanged && !buildVertexData(none, &drawable, bucket)) {
// Masking changed, need to rebuild this tile
geometryChanged = true;
}
});
// erase current drawable
removeTile(renderPass, tileID);
} else if (bucket.image) {
// build new drawable for this tile
buildDrawables(builder, bucket);
if (geometryChanged) {
removeTile(renderPass, tileID);
cleared = true;
} else if (0 < updated) {
// If we modified drawables without removing them, we're done with this tile.
continue;
}
}
// Otherwise, create new ones.
if (!builder) {
builder = createBuilder();
}
if (bucket.image && builder->getTextures().size() == 0) {
setTextures(builder, bucket);
};
buildVertexData(builder, /*drawable=*/nullptr, bucket);
// finish
builder->flush();
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -8,11 +8,6 @@
namespace mbgl {
#if MLN_DRAWABLE_RENDERER
class RasterLayerTweaker;
using RasterLayerTweakerPtr = std::shared_ptr<RasterLayerTweaker>;
#endif // MLN_DRAWABLE_RENDERER
class ImageSourceRenderData;
class RasterProgram;
@@ -60,10 +55,6 @@ private:
void render(PaintParameters&) override;
#endif
#if MLN_DRAWABLE_RENDERER
void updateLayerTweaker();
#endif // MLN_DRAWABLE_RENDERER
// Paint properties
style::RasterPaintProperties::Unevaluated unevaluated;
const ImageSourceRenderData* imageData = nullptr;
@@ -75,6 +66,8 @@ private:
#if MLN_DRAWABLE_RENDERER
gfx::ShaderProgramBasePtr rasterShader;
std::optional<uint32_t> rasterSampler0;
std::optional<uint32_t> rasterSampler1;
LayerGroupPtr imageLayerGroup;
using RasterVertexVector = gfx::VertexVector<RasterLayoutVertex>;
@@ -88,9 +81,6 @@ private:
using RasterSegmentVector = SegmentVector<RasterAttributes>;
using RasterSegmentVectorPtr = std::shared_ptr<RasterSegmentVector>;
std::shared_ptr<RasterSegmentVector> staticDataSegments;
RasterLayerTweakerPtr tweaker;
bool overdrawInspector = false;
#endif
};

View File

@@ -29,6 +29,7 @@
#include <mbgl/gfx/collision_drawable_data.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/symbol_layer_tweaker.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/shaders/symbol_layer_ubo.hpp>
#include <mbgl/gfx/collision_drawable_data.hpp>
@@ -379,11 +380,10 @@ void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters)
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
if (layerGroup && layerGroup->getLayerTweaker()) {
#if MLN_RENDER_BACKEND_METAL
layerGroup->getLayerTweaker()->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
layerGroup->getLayerTweaker()->updateProperties(evaluatedProperties);
// The symbol tweaker supports updating properties.
// When the style changes, it will be replaced in `RenderLayer::layerChanged`
if (layerTweaker) {
layerTweaker->updateProperties(evaluatedProperties);
}
#endif // MLN_DRAWABLE_RENDERER
}
@@ -970,16 +970,19 @@ void RenderSymbolLayer::layerIndexChanged(int32_t newLayerIndex, UniqueChangeReq
changeLayerIndex(collisionTileLayerGroup, newLayerIndex, changes);
}
void RenderSymbolLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
std::size_t RenderSymbolLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
const auto oldValue = stats.drawablesRemoved;
if (const auto tileGroup = static_cast<TileLayerGroup*>(layerGroup.get())) {
stats.drawablesRemoved += tileGroup->removeDrawables(renderPass, tileID).size();
}
if (collisionTileLayerGroup) {
stats.drawablesRemoved += collisionTileLayerGroup->removeDrawables(renderPass, tileID).size();
}
return stats.drawablesRemoved - oldValue;
}
void RenderSymbolLayer::removeAllDrawables() {
std::size_t RenderSymbolLayer::removeAllDrawables() {
const auto oldValue = stats.drawablesRemoved;
if (layerGroup) {
stats.drawablesRemoved += layerGroup->getDrawableCount();
layerGroup->clearDrawables();
@@ -988,12 +991,13 @@ void RenderSymbolLayer::removeAllDrawables() {
stats.drawablesRemoved += collisionTileLayerGroup->getDrawableCount();
collisionTileLayerGroup->clearDrawables();
}
return stats.drawablesRemoved - oldValue;
}
void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const std::shared_ptr<UpdateParameters>& updateParameters,
const RenderTree& /*renderTree*/,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
@@ -1004,24 +1008,27 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// Set up a layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
tweaker = std::make_shared<SymbolLayerTweaker>(getID(), evaluatedProperties);
#if MLN_RENDER_BACKEND_METAL
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
#endif // MLN_RENDER_BACKEND_METAL
layerGroup_->setLayerTweaker(tweaker);
setLayerGroup(std::move(layerGroup_), changes);
}
}
if (!layerTweaker) {
layerTweaker = std::make_shared<SymbolLayerTweaker>(getID(), evaluatedProperties);
layerGroup->addLayerTweaker(layerTweaker);
}
layerTweaker->enableOverdrawInspector(!!(updateParameters->debugOptions & MapDebugOptions::Overdraw));
const auto& getCollisionTileLayerGroup = [&] {
if (!collisionTileLayerGroup) {
if ((collisionTileLayerGroup = context.createTileLayerGroup(
layerIndex, /*initialCapacity=*/64, getID() + "-collision"))) {
collisionTileLayerGroup->setLayerTweaker(
std::make_shared<CollisionLayerTweaker>(getID(), evaluatedProperties));
activateLayerGroup(collisionTileLayerGroup, true, changes);
}
}
if (!collisionLayerTweaker) {
collisionLayerTweaker = std::make_shared<CollisionLayerTweaker>(getID(), evaluatedProperties);
collisionTileLayerGroup->addLayerTweaker(collisionLayerTweaker);
}
return collisionTileLayerGroup;
};
@@ -1168,6 +1175,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// add drawables to layer group
for (auto& drawable : collisionBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(collisionLayerTweaker);
auto drawData = std::make_unique<gfx::CollisionDrawableData>(values.translate, values.translateAnchor);
drawable->setData(std::move(drawData));
group->addDrawable(passes, tileID, std::move(drawable));
@@ -1181,6 +1190,11 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// Just update the drawables we already created
tileLayerGroup->visitDrawables(passes, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
}
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
updateTileDrawable(
drawable, context, bucket, bucketPaintProperties, evaluated, state, textInterpUBO, iconInterpUBO);
@@ -1247,6 +1261,10 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto& bucket = static_cast<const SymbolBucket&>(*renderable.renderData.bucket);
const auto& buffer = isText ? bucket.text : (sdfIcons ? bucket.sdfIcon : bucket.icon);
if (!buffer.sharedTriangles->elements()) {
continue;
}
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderable.renderData.layerProperties);
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
@@ -1264,14 +1282,11 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto vertexCount = buffer.vertices().elements();
gfx::VertexAttributeArray attribs;
const auto uniformProps = updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs);
#if MLN_RENDER_BACKEND_METAL
propertiesAsUniforms = uniformProps;
if (tweaker) {
tweaker->setPropertiesAsUniforms(propertiesAsUniforms);
const auto propertiesAsUniforms = updateTileAttributes(
buffer, isText, bucketPaintProperties, evaluated, attribs);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
#endif // MLN_RENDER_BACKEND_METAL
const auto textHalo = evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0.0f &&
evaluated.get<style::TextHaloWidth>().constantOr(1);
@@ -1340,8 +1355,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
if (!shaderGroup) {
return;
}
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, uniformProps, StringIndexer::get(idPosOffsetAttribName)));
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(shaderGroup->getOrCreateShader(
context, propertiesAsUniforms, StringIndexer::get(idPosOffsetAttribName)));
if (!shader) {
return;
}
@@ -1359,6 +1374,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto drawData = std::make_unique<gfx::SymbolDrawableData>(
/*.isHalo=*/isHalo,

View File

@@ -118,10 +118,10 @@ protected:
void layerRemoved(UniqueChangeRequestVec&) override;
/// Remove all drawables for the tile from the layer group
void removeTile(RenderPass, const OverscaledTileID&) override;
std::size_t removeTile(RenderPass, const OverscaledTileID&) override;
/// Remove all the drawables for tiles
void removeAllDrawables() override;
std::size_t removeAllDrawables() override;
#endif // MLN_DRAWABLE_RENDERER
private:
@@ -151,8 +151,6 @@ private:
#endif // MLN_LEGACY_RENDERER
#if MLN_DRAWABLE_RENDERER
SymbolLayerTweakerPtr tweaker;
gfx::ShaderGroupPtr symbolIconGroup;
gfx::ShaderGroupPtr symbolSDFGroup;
gfx::ShaderGroupPtr symbolTextAndIconGroup;
@@ -160,11 +158,9 @@ private:
gfx::ShaderGroupPtr collisionBoxGroup;
gfx::ShaderGroupPtr collisionCircleGroup;
std::shared_ptr<TileLayerGroup> collisionTileLayerGroup;
#endif // MLN_DRAWABLE_RENDERER
#if MLN_RENDER_BACKEND_METAL
std::vector<std::string> propertiesAsUniforms;
#endif // MLN_RENDER_BACKEND_METAL
LayerTweakerPtr collisionLayerTweaker;
#endif // MLN_DRAWABLE_RENDERER
};
} // namespace mbgl

View File

@@ -90,7 +90,7 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
const auto zoom = parameters.state.getZoom();
#if MLN_RENDER_BACKEND_METAL
if (propertiesChanged) {
if (permutationUpdated) {
const SymbolPermutationUBO permutationUBO = {
/* .fill_color = */ {/*.source=*/getAttributeSource("a_fill_color"), /*.expression=*/{}},
/* .halo_color = */ {/*.source=*/getAttributeSource("a_halo_color"), /*.expression=*/{}},
@@ -108,7 +108,7 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
permutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
propertiesChanged = false;
permutationUpdated = false;
}
if (!expressionUniformBuffer) {
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
@@ -116,6 +116,12 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
}
#endif
if (propertiesUpdated) {
textPropertiesUpdated = true;
iconPropertiesUpdated = true;
propertiesUpdated = false;
}
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
return;
@@ -125,14 +131,15 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
const auto& symbolData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
const auto isText = (symbolData.symbolType == SymbolType::Text);
if (isText && (!textPaintBuffer || propertiesUpdated)) {
if (isText && (!textPaintBuffer || textPropertiesUpdated)) {
const auto props = buildPaintUBO(true, evaluated);
textPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
} else if (!isText && (!iconPaintBuffer || propertiesUpdated)) {
textPropertiesUpdated = false;
} else if (!isText && (!iconPaintBuffer || iconPropertiesUpdated)) {
const auto props = buildPaintUBO(false, evaluated);
iconPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
iconPropertiesUpdated = false;
}
propertiesUpdated = false;
// from RenderTile::translatedMatrix
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();

View File

@@ -30,6 +30,9 @@ private:
gfx::UniformBufferPtr textPaintBuffer;
gfx::UniformBufferPtr iconPaintBuffer;
bool textPropertiesUpdated = false;
bool iconPropertiesUpdated = false;
#if MLN_RENDER_BACKEND_METAL
gfx::UniformBufferPtr permutationUniformBuffer;
gfx::UniformBufferPtr expressionUniformBuffer;

View File

@@ -70,11 +70,41 @@ std::optional<Color> RenderLayer::getSolidBackground() const {
}
#if MLN_DRAWABLE_RENDERER
void RenderLayer::replaceTweaker(LayerTweakerPtr& curTweaker,
LayerTweakerPtr newTweaker,
const std::vector<LayerGroupBasePtr>& layerGroups) {
const auto prevTweaker = curTweaker;
// We need to re-create the tweaker because it doesn't yet support modifying evaluated
// properties, but we don't want to stop updating drawables (as in the `layerChanged` case)
// so we need to update the tweaker reference on the outstanding drawables so that they
// pass the check in `updateExisting`.
// TODO: Once the tweaker doesn't need to be re-created on each property evaluation, this won't be needed.
for (const auto& group : layerGroups) {
if (group) {
group->addLayerTweaker(newTweaker);
group->visitDrawables([&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() == prevTweaker) {
drawable.setLayerTweaker(newTweaker);
}
});
}
}
curTweaker = std::move(newTweaker);
}
void RenderLayer::layerChanged(const TransitionParameters&,
const Immutable<style::Layer::Impl>&,
UniqueChangeRequestVec&) {
// When a layer changes, the bucket won't be replaced until the new source(s) load.
// If we remove the drawables here, they will just be re-created based on the current data.
// Detach the layer tweaker, if any. This keeps the existing tiles up-to-date with the
// most recent evaluated properties, while a new one will be created along with new drawables
// when tiles are loaded and new buckets are available.
layerTweaker.reset();
}
void RenderLayer::layerRemoved(UniqueChangeRequestVec& changes) {
@@ -136,17 +166,23 @@ const LayerRenderData* RenderLayer::getRenderDataForPass(const RenderTile& tile,
}
#if MLN_DRAWABLE_RENDERER
void RenderLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
std::size_t RenderLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
if (const auto tileGroup = static_cast<TileLayerGroup*>(layerGroup.get())) {
stats.drawablesRemoved += tileGroup->removeDrawables(renderPass, tileID).size();
const auto n = tileGroup->removeDrawables(renderPass, tileID).size();
stats.drawablesRemoved += n;
return n;
}
return 0;
}
void RenderLayer::removeAllDrawables() {
std::size_t RenderLayer::removeAllDrawables() {
if (layerGroup) {
stats.drawablesRemoved += layerGroup->getDrawableCount();
const auto count = layerGroup->getDrawableCount();
stats.drawablesRemoved += count;
layerGroup->clearDrawables();
return count;
}
return 0;
}
void RenderLayer::updateRenderTileIDs() {

View File

@@ -211,10 +211,11 @@ protected:
void changeLayerIndex(const LayerGroupBasePtr&, int32_t newLayerIndex, UniqueChangeRequestVec&);
/// Remove all drawables for the tile from the layer group
virtual void removeTile(RenderPass, const OverscaledTileID&);
/// @return The number of drawables actually removed.
virtual std::size_t removeTile(RenderPass, const OverscaledTileID&);
/// Remove all the drawables for tiles
virtual void removeAllDrawables();
virtual std::size_t removeAllDrawables();
/// Update `renderTileIDs` from `renderTiles`
void updateRenderTileIDs();
@@ -233,6 +234,12 @@ protected:
/// @return true if updated, false if the tile ID is not present in the set of tiles to be rendered or the ID is
/// unchanged
bool setRenderTileBucketID(const OverscaledTileID&, util::SimpleIdentity bucketID);
/// Update the layer tweaker and drawables which reference it
static void replaceTweaker(LayerTweakerPtr& toReplace,
LayerTweakerPtr newTweaker,
const std::vector<LayerGroupBasePtr>&);
#endif // MLN_DRAWABLE_RENDERER
static bool applyColorRamp(const style::ColorRampPropertyValue&, PremultipliedImage&);
@@ -251,6 +258,9 @@ protected:
// will need to be overriden to handle their activation.
LayerGroupBasePtr layerGroup;
// An optional tweaker that will update drawables
LayerTweakerPtr layerTweaker;
// The set of Tile IDs in `renderTiles`, along with the
// identity of the bucket from which they were built.
std::unordered_map<OverscaledTileID, util::SimpleIdentity> renderTileIDs;

View File

@@ -6,6 +6,7 @@
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layer_tweaker.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tree.hpp>
namespace mbgl {
@@ -84,11 +85,7 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
"render target", {*offscreenTexture, Color{0.0f, 0.0f, 0.0f, 1.0f}, {}, {}});
// Run layer tweakers to update any dynamic elements
visitLayerGroups([&](LayerGroupBase& layerGroup) {
if (layerGroup.getLayerTweaker()) {
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
}
});
visitLayerGroups([&](LayerGroupBase& layerGroup) { layerGroup.runTweakers(renderTree, parameters); });
// draw layer groups, opaque pass
parameters.pass = RenderPass::Opaque;

View File

@@ -152,11 +152,8 @@ void Renderer::Impl::render(const RenderTree& renderTree,
#endif
// Tweakers are run in the upload pass so they can set up uniforms.
orchestrator.visitLayerGroups([&](LayerGroupBase& layerGroup) {
if (layerGroup.getLayerTweaker()) {
layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters);
}
});
orchestrator.visitLayerGroups(
[&](LayerGroupBase& layerGroup) { layerGroup.runTweakers(renderTree, parameters); });
}
// Update the debug layer groups