Handle updated evaluated properties in the fill layer tweaker instead of replacing it on every update (#1707)
This commit is contained in:
@@ -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(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
};
|
||||
|
||||
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(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
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(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillPatternPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
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(¶msUBO, sizeof(paramsUBO));
|
||||
context.emplaceOrUpdateUniformBuffer(fillOutlinePatternPropsUniformBuffer, ¶msUBO);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user