Handle updated evaluated properties in the fill layer tweaker instead of replacing it on every update (#1707)

This commit is contained in:
Tim Sylvester
2023-10-02 08:29:57 -07:00
committed by GitHub
parent 3f1807a11a
commit 59a5edb1ea
2 changed files with 42 additions and 68 deletions

View File

@@ -77,13 +77,15 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
// Only run each update function once
bool fillUniformBufferUpdated = false;
bool fillOutlineUniformBufferUpdated = false;
bool fillPatternUniformBufferUpdated = false;
bool fillOutlinePatternUniformBufferUpdated = false;
auto UpdateFillUniformBuffers = [&]() {
const auto UpdateFillUniformBuffers = [&]() {
if (fillUniformBufferUpdated) return;
fillUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (propertiesChanged || !fillPermutationUniformBuffer) {
@@ -99,16 +101,11 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
};
if (fillPermutationUniformBuffer) {
fillPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
fillPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO, sizeof(permutationUBO));
}
fillUniformBufferUpdated = true;
context.emplaceOrUpdateUniformBuffer(fillPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillPropsUniformBuffer) {
if (!fillPropsUniformBuffer || propertiesUpdated) {
const FillEvaluatedPropsUBO paramsUBO = {
/* .color = */ evaluated.get<FillColor>().constantOr(FillColor::defaultValue()),
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
@@ -116,12 +113,13 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
0,
};
fillPropsUniformBuffer = context.createUniformBuffer(&paramsUBO, sizeof(paramsUBO));
context.emplaceOrUpdateUniformBuffer(fillPropsUniformBuffer, &paramsUBO);
}
};
auto UpdateFillOutlineUniformBuffers = [&]() {
const auto UpdateFillOutlineUniformBuffers = [&]() {
if (fillOutlineUniformBufferUpdated) return;
fillOutlineUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (propertiesChanged || !fillOutlinePermutationUniformBuffer) {
@@ -137,17 +135,11 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
0,
};
if (fillOutlinePermutationUniformBuffer) {
fillOutlinePermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
fillOutlinePermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
sizeof(permutationUBO));
}
context.emplaceOrUpdateUniformBuffer(fillOutlinePermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillOutlinePropsUniformBuffer) {
if (!fillOutlinePropsUniformBuffer || propertiesUpdated) {
const FillOutlineEvaluatedPropsUBO paramsUBO = {
/* .outline_color = */ evaluated.get<FillOutlineColor>().constantOr(FillOutlineColor::defaultValue()),
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
@@ -155,55 +147,47 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
0,
};
fillOutlinePropsUniformBuffer = context.createUniformBuffer(&paramsUBO, sizeof(paramsUBO));
context.emplaceOrUpdateUniformBuffer(fillOutlinePropsUniformBuffer, &paramsUBO);
}
fillOutlineUniformBufferUpdated = true;
};
auto UpdateFillPatternUniformBuffers = [&]() {
const auto UpdateFillPatternUniformBuffers = [&]() {
if (fillPatternUniformBufferUpdated) return;
fillPatternUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (propertiesChanged || !fillPatternPermutationUniformBuffer) {
const FillPatternPermutationUBO permutationUBO = {
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(1),
/* .pattern_from = */ {/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(1),
/*.expression=*/{}},
/* .pattern_to = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(2), /*.expression=*/{}},
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(2), /*.expression=*/{}},
/* .opacity = */
{/*.source=*/getAttributeSource<BuiltIn::FillOutlinePatternShader>(3), /*.expression=*/{}},
{/*.source=*/getAttributeSource<BuiltIn::FillPatternShader>(3), /*.expression=*/{}},
/* .overdrawInspector = */ overdrawInspector,
0,
0,
0,
0,
};
if (fillPatternPermutationUniformBuffer) {
fillPatternPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
fillPatternPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
sizeof(permutationUBO));
}
context.emplaceOrUpdateUniformBuffer(fillPatternPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillPatternPropsUniformBuffer) {
if (!fillPatternPropsUniformBuffer || propertiesUpdated) {
const FillPatternEvaluatedPropsUBO paramsUBO = {
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
/* .fade = */ crossfade.t,
0,
0,
};
fillPatternPropsUniformBuffer = context.createUniformBuffer(&paramsUBO, sizeof(paramsUBO));
context.emplaceOrUpdateUniformBuffer(fillPatternPropsUniformBuffer, &paramsUBO);
}
fillPatternUniformBufferUpdated = true;
};
auto UpdateFillOutlinePatternUniformBuffers = [&]() {
const auto UpdateFillOutlinePatternUniformBuffers = [&]() {
if (fillOutlinePatternUniformBufferUpdated) return;
fillOutlinePatternUniformBufferUpdated = true;
#if MLN_RENDER_BACKEND_METAL
if (propertiesChanged || !fillOutlinePatternPermutationUniformBuffer) {
@@ -220,57 +204,47 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
0,
};
if (fillOutlinePatternPermutationUniformBuffer) {
fillOutlinePatternPermutationUniformBuffer->update(&permutationUBO, sizeof(permutationUBO));
} else {
fillOutlinePatternPermutationUniformBuffer = context.createUniformBuffer(&permutationUBO,
sizeof(permutationUBO));
}
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPermutationUniformBuffer, &permutationUBO);
}
#endif
if (!fillOutlinePatternPropsUniformBuffer) {
if (!fillOutlinePatternPropsUniformBuffer || propertiesUpdated) {
const FillOutlinePatternEvaluatedPropsUBO paramsUBO = {
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
/* .fade = */ crossfade.t,
0,
0,
};
fillOutlinePatternPropsUniformBuffer = context.createUniformBuffer(&paramsUBO, sizeof(paramsUBO));
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPropsUniformBuffer, &paramsUBO);
}
fillOutlinePatternUniformBufferUpdated = true;
};
#if MLN_RENDER_BACKEND_METAL
if (!expressionUniformBuffer) {
const auto zoom = parameters.state.getZoom();
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
expressionUniformBuffer = context.createUniformBuffer(&expressionUBO, sizeof(expressionUBO));
}
const auto zoom = parameters.state.getZoom();
const auto expressionUBO = buildExpressionUBO(zoom, parameters.frameCount);
context.emplaceOrUpdateUniformBuffer(expressionUniformBuffer, &expressionUBO);
#endif
const auto& translation = evaluated.get<FillTranslate>();
const auto anchor = evaluated.get<FillTranslateAnchor>();
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
const auto intZoom = parameters.state.getIntegerZoom();
const auto pixelRatio = parameters.pixelRatio;
layerGroup.visitDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
auto& uniforms = drawable.mutableUniformBuffers();
// auto& drawableType = drawable.getShader()->typeName();
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto& translation = evaluated.get<FillTranslate>();
const auto anchor = evaluated.get<FillTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
constexpr bool nearClipped = false;
const auto matrix = getTileMatrix(
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
// from FillPatternProgram::layoutUniformValues
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
const auto intZoom = parameters.state.getIntegerZoom();
const auto tileRatio = 1.0f / tileID.pixelsToTileUnits(1.0f, intZoom);
const int32_t tileSizeAtNearestZoom = static_cast<int32_t>(
util::tileSize_D * parameters.state.zoomScale(intZoom - tileID.canonical.z));
@@ -278,7 +252,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
tileSizeAtNearestZoom *
(tileID.canonical.x + tileID.wrap * parameters.state.zoomScale(tileID.canonical.z)));
const int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
const auto pixelRatio = parameters.pixelRatio;
Size textureSize = {0, 0};
if (const auto shader = drawable.getShader()) {
@@ -289,12 +262,13 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
}
}
auto& uniforms = drawable.mutableUniformBuffers();
if (uniforms.get(idFillInterpolateUBOName)) {
UpdateFillUniformBuffers();
uniforms.addOrReplace(idFillEvaluatedPropsUBOName, fillPropsUniformBuffer);
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
uniforms.createOrUpdate(idFillDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
@@ -304,12 +278,12 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
UpdateFillOutlineUniformBuffers();
uniforms.addOrReplace(idFillOutlineEvaluatedPropsUBOName, fillOutlinePropsUniformBuffer);
const FillOutlineDrawableUBO drawableUBO = {
/*.matrix=*/util::cast<float>(matrix),
/*.world=*/{(float)renderableSize.width, (float)renderableSize.height},
/* pad1 */ 0,
/* pad2 */ 0};
uniforms.createOrUpdate(idFillOutlineDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
@@ -319,6 +293,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
UpdateFillPatternUniformBuffers();
uniforms.addOrReplace(idFillPatternEvaluatedPropsUBOName, fillPatternPropsUniformBuffer);
const FillPatternDrawableUBO drawableUBO = {
/*.matrix=*/util::cast<float>(matrix),
/*.scale=*/{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale},
@@ -328,7 +303,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
0,
0,
};
uniforms.createOrUpdate(idFillPatternDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
@@ -338,6 +312,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
UpdateFillOutlinePatternUniformBuffers();
uniforms.addOrReplace(idFillOutlinePatternEvaluatedPropsUBOName, fillOutlinePatternPropsUniformBuffer);
const FillOutlinePatternDrawableUBO drawableUBO = {
/*.matrix=*/util::cast<float>(matrix),
/*.scale=*/{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale},
@@ -346,7 +321,6 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
/*.pixel_coord_lower=*/{static_cast<float>(pixelX & 0xFFFF), static_cast<float>(pixelY & 0xFFFF)},
/*.texsize=*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
};
uniforms.createOrUpdate(idFillOutlinePatternDrawableUBOName, &drawableUBO, context);
#if MLN_RENDER_BACKEND_METAL
@@ -360,6 +334,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
});
propertiesChanged = false;
propertiesUpdated = false;
}
} // namespace mbgl

View File

@@ -103,9 +103,8 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
evaluatedProperties = std::move(properties);
#if MLN_DRAWABLE_RENDERER
if (layerGroup) {
auto newTweaker = std::make_shared<FillLayerTweaker>(getID(), evaluatedProperties);
replaceTweaker(layerTweaker, std::move(newTweaker), {layerGroup});
if (layerTweaker) {
layerTweaker->updateProperties(evaluatedProperties);
}
#endif
}