Share identical uniform buffers across drawables for background, line. (#1346)
This commit is contained in:
committed by
Bart Louwers
parent
3056f28756
commit
4eef2e3529
@@ -62,7 +62,9 @@ public:
|
||||
void createOrUpdate(std::string_view name, const std::vector<uint8_t>& data, gfx::Context&);
|
||||
void createOrUpdate(std::string_view name, const void* data, std::size_t size, gfx::Context&);
|
||||
template <typename T>
|
||||
void createOrUpdate(std::string_view name, const T* data, gfx::Context& context) {
|
||||
std::enable_if_t<!std::is_pointer_v<T>> createOrUpdate(std::string_view name,
|
||||
const T* data,
|
||||
gfx::Context& context) {
|
||||
createOrUpdate(name, data, sizeof(T), context);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
virtual void postRender(RenderOrchestrator&, PaintParameters&) {}
|
||||
|
||||
/// Call the provided function for each drawable in priority order
|
||||
virtual void observeDrawables(const std::function<void(gfx::Drawable&)>&&) = 0;
|
||||
virtual void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const = 0;
|
||||
virtual std::size_t observeDrawables(const std::function<void(gfx::Drawable&)>&&) = 0;
|
||||
virtual std::size_t observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const = 0;
|
||||
|
||||
/// Call the provided function for each drawable in undefined order, allowing for removal.
|
||||
/// @param f A function called with each drawable, returning true to keep and false to discard it.
|
||||
@@ -102,15 +102,17 @@ public:
|
||||
std::vector<gfx::UniqueDrawable> removeDrawables(mbgl::RenderPass, const OverscaledTileID&);
|
||||
void addDrawable(mbgl::RenderPass, const OverscaledTileID&, gfx::UniqueDrawable&&);
|
||||
|
||||
void observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
std::size_t observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&&) override;
|
||||
|
||||
/// Call the provided function for each drawable for the given tile
|
||||
void observeDrawables(mbgl::RenderPass, const OverscaledTileID&, const std::function<void(gfx::Drawable&)>&&);
|
||||
void observeDrawables(mbgl::RenderPass,
|
||||
const OverscaledTileID&,
|
||||
const std::function<void(const gfx::Drawable&)>&&) const;
|
||||
std::size_t observeDrawables(mbgl::RenderPass,
|
||||
const OverscaledTileID&,
|
||||
const std::function<void(gfx::Drawable&)>&&);
|
||||
std::size_t observeDrawables(mbgl::RenderPass,
|
||||
const OverscaledTileID&,
|
||||
const std::function<void(const gfx::Drawable&)>&&) const;
|
||||
|
||||
std::size_t clearDrawables() override;
|
||||
|
||||
@@ -133,8 +135,8 @@ public:
|
||||
std::vector<gfx::UniqueDrawable> removeDrawables(mbgl::RenderPass);
|
||||
void addDrawable(gfx::UniqueDrawable&&);
|
||||
|
||||
void observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
void observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawables(const std::function<void(gfx::Drawable&)>&&) override;
|
||||
std::size_t observeDrawables(const std::function<void(const gfx::Drawable&)>&&) const override;
|
||||
std::size_t observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&&) override;
|
||||
|
||||
std::size_t clearDrawables() override;
|
||||
|
||||
@@ -27,20 +27,22 @@ void LayerGroup::addDrawable(gfx::UniqueDrawable&& drawable) {
|
||||
impl->drawables.emplace(std::move(drawable));
|
||||
}
|
||||
|
||||
void LayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
std::size_t LayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
for (const auto& item : impl->drawables) {
|
||||
if (item) {
|
||||
f(*item);
|
||||
}
|
||||
}
|
||||
return impl->drawables.size();
|
||||
}
|
||||
|
||||
void LayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
std::size_t LayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
for (const auto& item : impl->drawables) {
|
||||
if (item) {
|
||||
f(*item);
|
||||
}
|
||||
}
|
||||
return impl->drawables.size();
|
||||
}
|
||||
|
||||
std::size_t LayerGroup::observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&& f) {
|
||||
|
||||
@@ -138,12 +138,16 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const RenderTre
|
||||
};
|
||||
uniforms.createOrUpdate(BackgroundLayerUBOName, &layerUBO, context);
|
||||
} else {
|
||||
const BackgroundLayerUBO layerUBO = {/* .color = */ evaluated.get<BackgroundColor>(),
|
||||
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
0};
|
||||
uniforms.createOrUpdate(BackgroundLayerUBOName, &layerUBO, context);
|
||||
// UBOs can be shared
|
||||
if (!backgroundLayerBuffer) {
|
||||
const BackgroundLayerUBO layerUBO = {/* .color = */ evaluated.get<BackgroundColor>(),
|
||||
/* .opacity = */ evaluated.get<BackgroundOpacity>(),
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
0};
|
||||
backgroundLayerBuffer = context.createUniformBuffer(&layerUBO, sizeof(layerUBO));
|
||||
}
|
||||
uniforms.addOrReplace(BackgroundLayerUBOName, backgroundLayerBuffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) override;
|
||||
|
||||
protected:
|
||||
gfx::UniformBufferPtr backgroundLayerBuffer;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -47,6 +47,7 @@ static constexpr std::string_view CircleEvaluatedPropsUBOName = "CircleEvaluated
|
||||
void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
if (layerGroup.empty()) {
|
||||
@@ -58,19 +59,21 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
// Updated every frame, but shared across drawables
|
||||
const CirclePaintParamsUBO paintParamsUBO = {
|
||||
/* .camera_to_center_distance = */ parameters.state.getCameraToCenterDistance(),
|
||||
/* .device_pixel_ratio = */ parameters.pixelRatio,
|
||||
/* .padding = */ {0}};
|
||||
|
||||
if (!paintParamsUniformBuffer) {
|
||||
paintParamsUniformBuffer = parameters.context.createUniformBuffer(&paintParamsUBO, sizeof(paintParamsUBO));
|
||||
paintParamsUniformBuffer = context.createUniformBuffer(&paintParamsUBO, sizeof(paintParamsUBO));
|
||||
} else {
|
||||
paintParamsUniformBuffer->update(&paintParamsUBO, sizeof(CirclePaintParamsUBO));
|
||||
}
|
||||
|
||||
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
|
||||
|
||||
// Updated only with evaluated properties
|
||||
if (!evaluatedPropsUniformBuffer) {
|
||||
const CircleEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
/* .color = */ evaluated.get<CircleColor>().constantOr(CircleColor::defaultValue()),
|
||||
@@ -84,13 +87,13 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* .scale_with_map = */ evaluated.get<CirclePitchScale>() == CirclePitchScaleType::Map,
|
||||
/* .pitch_with_map = */ pitchWithMap,
|
||||
/* .padding = */ 0};
|
||||
evaluatedPropsUniformBuffer = parameters.context.createUniformBuffer(&evaluatedPropsUBO,
|
||||
sizeof(evaluatedPropsUBO));
|
||||
evaluatedPropsUniformBuffer = context.createUniformBuffer(&evaluatedPropsUBO, sizeof(evaluatedPropsUBO));
|
||||
}
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
drawable.mutableUniformBuffers().addOrReplace(CirclePaintParamsUBOName, paintParamsUniformBuffer);
|
||||
drawable.mutableUniformBuffers().addOrReplace(CircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.addOrReplace(CirclePaintParamsUBOName, paintParamsUniformBuffer);
|
||||
uniforms.addOrReplace(CircleEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
|
||||
|
||||
if (!drawable.getTileID()) {
|
||||
return;
|
||||
@@ -106,13 +109,14 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
|
||||
const auto pixelsToTileUnits = tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom()));
|
||||
|
||||
CircleDrawableUBO drawableUBO = {
|
||||
// Updated for each drawable on each frame
|
||||
const CircleDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .extrude_scale = */
|
||||
pitchWithMap ? std::array<float, 2>{{pixelsToTileUnits}} : parameters.pixelsToGLUnits,
|
||||
/* .padding = */ {0}};
|
||||
|
||||
drawable.mutableUniformBuffers().createOrUpdate(CircleDrawableUBOName, &drawableUBO, parameters.context);
|
||||
uniforms.createOrUpdate(CircleDrawableUBOName, &drawableUBO, context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ auto constOrDefault(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& evalua
|
||||
void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto& props = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties);
|
||||
const auto& evaluated = props.evaluated;
|
||||
const auto& crossfade = props.crossfade;
|
||||
@@ -78,7 +79,8 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
// UBO depends on more than just evaluated properties, so we need to update every time.
|
||||
// UBO depends on more than just evaluated properties, so we need to update every time,
|
||||
// but the resulting buffer can be shared across all the drawables from the layer.
|
||||
const FillExtrusionDrawablePropsUBO paramsUBO = {
|
||||
/* .color = */ gfx::VertexAttribute::colorAttrRGBA(constOrDefault<FillExtrusionColor>(evaluated)),
|
||||
/* .light_color = */ FillExtrusionProgram::lightColor(parameters.evaluatedLight),
|
||||
@@ -94,7 +96,7 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0};
|
||||
if (!propsBuffer) {
|
||||
propsBuffer = parameters.context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
propsBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
} else {
|
||||
propsBuffer->update(¶msUBO, sizeof(paramsUBO));
|
||||
}
|
||||
@@ -145,7 +147,7 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* .height_factor = */ heightFactor,
|
||||
/* .pad = */ 0};
|
||||
|
||||
uniforms.createOrUpdate(FillExtrusionDrawableUBOName, &drawableUBO, parameters.context);
|
||||
uniforms.createOrUpdate(FillExtrusionDrawableUBOName, &drawableUBO, context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ static constexpr std::string_view FillDrawablePropsUBOName = "FillDrawablePropsU
|
||||
void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto& props = static_cast<const FillLayerProperties&>(*evaluatedProperties);
|
||||
const auto& evaluated = props.evaluated;
|
||||
const auto& crossfade = props.crossfade;
|
||||
@@ -65,11 +66,12 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* .padding = */ 0,
|
||||
0,
|
||||
0};
|
||||
propsBuffer = parameters.context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
propsBuffer = context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
}
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
drawable.mutableUniformBuffers().addOrReplace(FillDrawablePropsUBOName, propsBuffer);
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.addOrReplace(FillDrawablePropsUBOName, propsBuffer);
|
||||
|
||||
if (!drawable.getTileID()) {
|
||||
return;
|
||||
@@ -114,7 +116,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*.texsize=*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
};
|
||||
|
||||
drawable.mutableUniformBuffers().createOrUpdate(FillDrawableUBOName, &drawableUBO, parameters.context);
|
||||
uniforms.createOrUpdate(FillDrawableUBOName, &drawableUBO, context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ static constexpr std::string_view HeatmapEvaluatedPropsUBOName = "HeatmapEvaluat
|
||||
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
if (layerGroup.empty()) {
|
||||
@@ -46,7 +47,7 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
#endif
|
||||
|
||||
if (!evaluatedPropsUniformBuffer) {
|
||||
HeatmapEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
const HeatmapEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
/* .weight = */ evaluated.get<HeatmapWeight>().constantOr(HeatmapWeight::defaultValue()),
|
||||
/* .radius = */ evaluated.get<HeatmapRadius>().constantOr(HeatmapRadius::defaultValue()),
|
||||
/* .intensity = */ evaluated.get<HeatmapIntensity>(),
|
||||
@@ -56,7 +57,8 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
}
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
drawable.mutableUniformBuffers().addOrReplace(HeatmapEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.addOrReplace(HeatmapEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);
|
||||
|
||||
if (!drawable.getTileID()) {
|
||||
return;
|
||||
@@ -71,12 +73,12 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
TranslateAnchorType::Viewport,
|
||||
nearClipped,
|
||||
inViewportPixelUnits);
|
||||
HeatmapDrawableUBO drawableUBO = {
|
||||
const HeatmapDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/* .padding = */ {0}};
|
||||
|
||||
drawable.mutableUniformBuffers().createOrUpdate(HeatmapDrawableUBOName, &drawableUBO, parameters.context);
|
||||
uniforms.createOrUpdate(HeatmapDrawableUBOName, &drawableUBO, context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ void HeatmapTextureLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto& size = parameters.staticData.backendSize;
|
||||
mat4 viewportMat;
|
||||
matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
|
||||
HeatmapTextureDrawableUBO drawableUBO = {
|
||||
const HeatmapTextureDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(viewportMat),
|
||||
/* .world = */ {static_cast<float>(size.width), static_cast<float>(size.height)},
|
||||
/* .opacity = */ evaluated.get<HeatmapOpacity>(),
|
||||
|
||||
@@ -120,35 +120,55 @@ static constexpr std::string_view LineSDFPropertiesUBOName = "LineSDFPropertiesU
|
||||
void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
auto& context = parameters.context;
|
||||
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const LineLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
|
||||
const LinePropertiesUBO linePropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
const LineGradientPropertiesUBO lineGradientPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
const LineSDFPropertiesUBO lineSDFPropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
/*floorwidth =*/evaluated.get<LineFloorWidth>().constantOr(LineFloorWidth::defaultValue()),
|
||||
{0, 0}};
|
||||
const auto getLinePropsBuffer = [&]() {
|
||||
if (!linePropertiesBuffer) {
|
||||
const LinePropertiesUBO linePropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
linePropertiesBuffer = context.createUniformBuffer(&linePropertiesUBO, sizeof(linePropertiesUBO));
|
||||
}
|
||||
return linePropertiesBuffer;
|
||||
};
|
||||
const auto getLineGradientPropsBuffer = [&]() {
|
||||
if (!lineGradientPropertiesBuffer) {
|
||||
const LineGradientPropertiesUBO lineGradientPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
lineGradientPropertiesBuffer = context.createUniformBuffer(&lineGradientPropertiesUBO,
|
||||
sizeof(lineGradientPropertiesUBO));
|
||||
}
|
||||
return lineGradientPropertiesBuffer;
|
||||
};
|
||||
const auto getLineSDFPropsBuffer = [&]() {
|
||||
if (!lineSDFPropertiesBuffer) {
|
||||
const LineSDFPropertiesUBO lineSDFPropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
/*floorwidth =*/evaluated.get<LineFloorWidth>().constantOr(LineFloorWidth::defaultValue()),
|
||||
{0, 0}};
|
||||
lineSDFPropertiesBuffer = context.createUniformBuffer(&lineSDFPropertiesUBO, sizeof(lineSDFPropertiesUBO));
|
||||
}
|
||||
return lineSDFPropertiesBuffer;
|
||||
};
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
const auto shader = drawable.getShader();
|
||||
@@ -175,11 +195,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineUBOName, &lineUBO, sizeof(lineUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineUBOName, &lineUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.createOrUpdate(
|
||||
LinePropertiesUBOName, &linePropertiesUBO, sizeof(linePropertiesUBO), parameters.context);
|
||||
uniforms.addOrReplace(LinePropertiesUBOName, getLinePropsBuffer());
|
||||
}
|
||||
// gradient line
|
||||
else if (shaderUniforms.get(std::string(LineGradientUBOName))) {
|
||||
@@ -189,13 +208,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineGradientUBOName, &lineGradientUBO, sizeof(lineGradientUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineGradientUBOName, &lineGradientUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.createOrUpdate(LineGradientPropertiesUBOName,
|
||||
&lineGradientPropertiesUBO,
|
||||
sizeof(lineGradientPropertiesUBO),
|
||||
parameters.context);
|
||||
uniforms.addOrReplace(LineGradientPropertiesUBOName, getLineGradientPropsBuffer());
|
||||
}
|
||||
// pattern line
|
||||
else if (shaderUniforms.get(std::string(LinePatternUBOName))) {
|
||||
@@ -219,7 +235,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*device_pixel_ratio =*/parameters.pixelRatio,
|
||||
/*fade =*/crossfade.t,
|
||||
0};
|
||||
uniforms.createOrUpdate(LinePatternUBOName, &linePatternUBO, sizeof(linePatternUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LinePatternUBOName, &linePatternUBO, context);
|
||||
|
||||
// properties UBO
|
||||
const LinePatternPropertiesUBO linePatternPropertiesUBO{
|
||||
@@ -230,10 +246,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
uniforms.createOrUpdate(LinePatternPropertiesUBOName,
|
||||
&linePatternPropertiesUBO,
|
||||
sizeof(linePatternPropertiesUBO),
|
||||
parameters.context);
|
||||
uniforms.createOrUpdate(LinePatternPropertiesUBOName, &linePatternPropertiesUBO, context);
|
||||
}
|
||||
// SDF line
|
||||
else if (shaderUniforms.get(std::string(LineSDFUBOName))) {
|
||||
@@ -273,11 +286,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* sdfgamma = */ static_cast<float>(dashPatternTexture.getSize().width) /
|
||||
(std::min(widthA, widthB) * 256.0f * parameters.pixelRatio) / 2.0f,
|
||||
/* mix = */ crossfade.t};
|
||||
uniforms.createOrUpdate(LineSDFUBOName, &lineSDFUBO, sizeof(lineSDFUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineSDFUBOName, &lineSDFUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.createOrUpdate(
|
||||
LineSDFPropertiesUBOName, &lineSDFPropertiesUBO, sizeof(lineSDFPropertiesUBO), parameters.context);
|
||||
uniforms.addOrReplace(LineSDFPropertiesUBOName, getLineSDFPropsBuffer());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,10 +19,14 @@ public:
|
||||
LineLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||
: LayerTweaker(properties){};
|
||||
|
||||
public:
|
||||
~LineLayerTweaker() override = default;
|
||||
|
||||
void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) override;
|
||||
|
||||
protected:
|
||||
gfx::UniformBufferPtr linePropertiesBuffer;
|
||||
gfx::UniformBufferPtr lineGradientPropertiesBuffer;
|
||||
gfx::UniformBufferPtr lineSDFPropertiesBuffer;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -38,7 +38,7 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
|
||||
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
auto spinWeights = [](float spin) -> std::array<float, 4> {
|
||||
const auto spinWeights = [](float spin) -> std::array<float, 4> {
|
||||
spin = util::deg2radf(spin);
|
||||
const float s = std::sin(spin);
|
||||
const float c = std::cos(spin);
|
||||
@@ -46,14 +46,14 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
|
||||
{(2 * c + 1) / 3, (-std::sqrt(3.0f) * s - c + 1) / 3, (std::sqrt(3.0f) * s - c + 1) / 3, 0}};
|
||||
return spin_weights;
|
||||
};
|
||||
auto saturationFactor = [](float saturation) -> float {
|
||||
const auto saturationFactor = [](float saturation) -> float {
|
||||
if (saturation > 0) {
|
||||
return 1.f - 1.f / (1.001f - saturation);
|
||||
} else {
|
||||
return -saturation;
|
||||
}
|
||||
};
|
||||
auto contrastFactor = [](float contrast) -> float {
|
||||
const auto contrastFactor = [](float contrast) -> float {
|
||||
if (contrast > 0) {
|
||||
return 1 / (1 - contrast);
|
||||
} else {
|
||||
@@ -93,7 +93,7 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
|
||||
0,
|
||||
0};
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate("RasterDrawableUBO", &drawableUBO, sizeof(drawableUBO), parameters.context);
|
||||
uniforms.createOrUpdate("RasterDrawableUBO", &drawableUBO, parameters.context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -352,14 +352,17 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
std::get<0>(paintPropertyBinders.get<CircleStrokeOpacity>()->interpolationFactor(zoom)),
|
||||
/* .padding = */ 0};
|
||||
|
||||
tileLayerGroup->observeDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
|
||||
drawable.mutableUniformBuffers().createOrUpdate(CircleInterpolateUBOName, &interpolateUBO, context);
|
||||
});
|
||||
|
||||
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
|
||||
// If there are already drawables for this tile, update their UBOs and move on to the next tile.
|
||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(CircleInterpolateUBOName, &interpolateUBO, context);
|
||||
};
|
||||
if (0 < tileLayerGroup->observeDrawables(renderPass, tileID, std::move(updateExisting))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
|
||||
|
||||
gfx::VertexAttributeArray circleVertexAttrs;
|
||||
const auto propertiesAsUniforms = circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
|
||||
CircleRadius,
|
||||
@@ -400,7 +403,9 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
for (auto& drawable : circleBuilder->clearDrawables()) {
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().createOrUpdate(CircleInterpolateUBOName, &interpolateUBO, context);
|
||||
|
||||
auto& uniforms = drawable->mutableUniformBuffers();
|
||||
uniforms.addOrReplace(CircleInterpolateUBOName, interpBuffer);
|
||||
|
||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||
++stats.drawablesAdded;
|
||||
|
||||
@@ -399,25 +399,25 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
/* .padding = */ 0,
|
||||
0};
|
||||
|
||||
// TODO: only update if properties re-evaluated?
|
||||
const FillDrawableTilePropsUBO tileProps = {
|
||||
/* pattern_from = */ patternPosA ? util::cast<float>(patternPosA->tlbr()) : std::array<float, 4>{0},
|
||||
/* pattern_to = */ patternPosB ? util::cast<float>(patternPosB->tlbr()) : std::array<float, 4>{0},
|
||||
};
|
||||
|
||||
// If we already have drawables for this tile, update them.
|
||||
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) {
|
||||
// TODO: Share buffers
|
||||
tileLayerGroup->observeDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
FillLayerTweaker::FillInterpolateUBOName, &interpolateUBO, context);
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
FillLayerTweaker::FillTilePropsUBOName, &tileProps, context);
|
||||
});
|
||||
|
||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(FillLayerTweaker::FillInterpolateUBOName, &interpolateUBO, context);
|
||||
uniforms.createOrUpdate(FillLayerTweaker::FillTilePropsUBOName, &tileProps, context);
|
||||
};
|
||||
if (0 < tileLayerGroup->observeDrawables(renderPass, tileID, std::move(updateExisting))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Share UBO buffers among any drawables created for this tile
|
||||
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
|
||||
const auto tilePropsBuffer = context.createUniformBuffer(&tileProps, sizeof(tileProps));
|
||||
|
||||
// `Fill*Program` all use `style::FillPaintProperties`
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
const auto uniformProps =
|
||||
|
||||
@@ -121,11 +121,11 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto isText = (symbolData.symbolType == SymbolType::Text);
|
||||
|
||||
if (isText && !textPaintBuffer) {
|
||||
auto props = buildPaintUBO(true, evaluated);
|
||||
const auto props = buildPaintUBO(true, evaluated);
|
||||
textPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
|
||||
}
|
||||
if (!isText && !iconPaintBuffer) {
|
||||
auto props = buildPaintUBO(false, evaluated);
|
||||
const auto props = buildPaintUBO(false, evaluated);
|
||||
iconPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
|
||||
}
|
||||
|
||||
|
||||
@@ -83,18 +83,20 @@ void TileLayerGroup::addDrawable(mbgl::RenderPass pass, const OverscaledTileID&
|
||||
}
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
std::size_t TileLayerGroup::observeDrawables(const std::function<void(gfx::Drawable&)>&& f) {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
for (auto* drawable : impl->sortedDrawables) {
|
||||
f(*drawable);
|
||||
}
|
||||
return impl->sortedDrawables.size();
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
std::size_t TileLayerGroup::observeDrawables(const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
for (const auto* drawable : impl->sortedDrawables) {
|
||||
f(*drawable);
|
||||
}
|
||||
return impl->sortedDrawables.size();
|
||||
}
|
||||
|
||||
std::size_t TileLayerGroup::observeDrawablesRemove(const std::function<bool(gfx::Drawable&)>&& f) {
|
||||
@@ -114,20 +116,22 @@ std::size_t TileLayerGroup::observeDrawablesRemove(const std::function<bool(gfx:
|
||||
return (oldSize - impl->drawablesByTile.size());
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
const std::function<void(gfx::Drawable&)>&& f) {
|
||||
std::size_t TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
const std::function<void(gfx::Drawable&)>&& f) {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, tileID});
|
||||
std::for_each(range.first, range.second, [&f](const auto& pair) { f(*pair.second); });
|
||||
return std::distance(range.first, range.second);
|
||||
}
|
||||
|
||||
void TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
std::size_t TileLayerGroup::observeDrawables(mbgl::RenderPass pass,
|
||||
const OverscaledTileID& tileID,
|
||||
const std::function<void(const gfx::Drawable&)>&& f) const {
|
||||
assert(impl->drawablesByTile.size() == impl->sortedDrawables.size());
|
||||
const auto range = impl->drawablesByTile.equal_range({pass, tileID});
|
||||
std::for_each(range.first, range.second, [&f](const auto& pair) { f(*pair.second); });
|
||||
return std::distance(range.first, range.second);
|
||||
}
|
||||
|
||||
std::size_t TileLayerGroup::clearDrawables() {
|
||||
|
||||
@@ -378,7 +378,8 @@ void GeometryTileWorker::parse() {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> layerIDs(group.size());
|
||||
std::vector<std::string> layerIDs;
|
||||
layerIDs.reserve(group.size());
|
||||
for (const auto& layer : group) {
|
||||
layerIDs.push_back(layer->baseImpl->id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user