Move UBO updates from render layers to tweakers (#2703)

This commit is contained in:
Tim Sylvester
2024-09-10 11:37:50 -07:00
committed by GitHub
parent f74f4ff3cf
commit 29319a76bf
24 changed files with 563 additions and 657 deletions

View File

@@ -18,12 +18,16 @@
namespace mbgl {
class Bucket;
class Color;
class PaintParameters;
class LayerTweaker;
class PaintParameters;
class PaintPropertyBindersBase;
enum class RenderPass : uint8_t;
class RenderTile;
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
using RenderTiles = std::shared_ptr<const std::vector<std::reference_wrapper<const RenderTile>>>;
namespace gfx {
@@ -245,6 +249,17 @@ public:
/// Set origin point
void setOrigin(std::optional<Point<double>> p) { origin = std::move(p); }
/// Get the property binders used for property updates
PaintPropertyBindersBase* getBinders();
const PaintPropertyBindersBase* getBinders() const;
/// Set the property binders used for property updates
void setBinders(std::shared_ptr<Bucket>, PaintPropertyBindersBase*);
const RenderTile* getRenderTile() const;
const std::shared_ptr<Bucket>& getBucket() const;
void setRenderTile(Immutable<std::vector<RenderTile>>, const RenderTile*);
const std::chrono::duration<double> createTime = util::MonotonicTimer::now();
protected:

View File

@@ -23,10 +23,10 @@ class LayerProperties;
enum class TranslateAnchorType : bool;
} // namespace style
class TransformState;
class LayerGroupBase;
class PaintParameters;
class RenderTree;
class TransformState;
class UnwrappedTileID;
/**

View File

@@ -8,14 +8,14 @@
namespace mbgl {
#if MLN_USE_UNORDERED_DENSE
template <typename Key, typename Value>
using unordered_map = ankerl::unordered_dense::map<Key, Value>;
template <typename Key, typename Value, typename Hash = std::hash<Key>>
using unordered_map = ankerl::unordered_dense::map<Key, Value, Hash>;
template <typename Value>
using unordered_set = ankerl::unordered_dense::set<Value>;
#else
template <typename Key, typename Value>
using unordered_map = std::unordered_map<Key, Value>;
template <typename Key, typename Value, typename Hash = std::hash<Key>>
using unordered_map = std::unordered_map<Key, Value, Hash>;
template <typename Value>
using unordered_set = std::unordered_set<Value>;

View File

@@ -6,6 +6,7 @@
#include <mbgl/gfx/index_vector.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/renderer/render_pass.hpp>
#include <mbgl/renderer/render_tile.hpp>
namespace mbgl {
namespace gfx {
@@ -13,6 +14,12 @@ namespace gfx {
struct Drawable::Impl {
gfx::ColorMode colorMode = gfx::ColorMode::disabled();
gfx::CullFaceMode cullFaceMode = gfx::CullFaceMode::disabled();
std::shared_ptr<Bucket> bucket;
PaintPropertyBindersBase* binders = nullptr; // owned by `bucket`
Immutable<std::vector<RenderTile>> renderTiles = makeMutable<std::vector<RenderTile>>();
const RenderTile* renderTile = nullptr; // owned by `renderTiles`
};
Drawable::Drawable(std::string name_)
@@ -57,5 +64,31 @@ void Drawable::setTexture(std::shared_ptr<gfx::Texture2D> texture, size_t id) {
textures[id] = std::move(texture);
}
PaintPropertyBindersBase* Drawable::getBinders() {
return impl->binders;
}
const PaintPropertyBindersBase* Drawable::getBinders() const {
return impl->binders;
}
/// Set the property binders used for property updates
void Drawable::setBinders(std::shared_ptr<Bucket> bucket_, PaintPropertyBindersBase* binders_) {
impl->bucket = std::move(bucket_);
impl->binders = binders_;
}
const RenderTile* Drawable::getRenderTile() const {
return impl->renderTile;
}
const std::shared_ptr<Bucket>& Drawable::getBucket() const {
return impl->bucket;
}
void Drawable::setRenderTile(Immutable<std::vector<RenderTile>> renderTiles_, const RenderTile* tile_) {
impl->renderTiles = std::move(renderTiles_);
impl->renderTile = tile_;
}
} // namespace gfx
} // namespace mbgl

View File

@@ -2,6 +2,7 @@
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/programs/circle_program.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tree.hpp>
@@ -34,7 +35,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
const auto zoom = parameters.state.getZoom();
const auto zoom = static_cast<float>(parameters.state.getZoom());
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
const bool scaleWithMap = evaluated.get<CirclePitchScale>() == CirclePitchScaleType::Map;
@@ -64,6 +65,12 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto* binders = static_cast<CircleProgram::Binders*>(drawable.getBinders());
if (!binders) {
assert(false);
return;
}
const auto& translation = evaluated.get<CircleTranslate>();
const auto anchor = evaluated.get<CircleTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
@@ -71,7 +78,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
const auto pixelsToTileUnits = tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom));
const auto pixelsToTileUnits = tileID.pixelsToTileUnits(1.0f, zoom);
const auto extrudeScale = pitchWithMap ? std::array<float, 2>{pixelsToTileUnits, pixelsToTileUnits}
: parameters.pixelsToGLUnits;
@@ -82,6 +89,20 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idCircleDrawableUBO, &drawableUBO, context);
const CircleInterpolateUBO interpolateUBO = {
/* .color_t = */ std::get<0>(binders->get<CircleColor>()->interpolationFactor(zoom)),
/* .radius_t = */ std::get<0>(binders->get<CircleRadius>()->interpolationFactor(zoom)),
/* .blur_t = */ std::get<0>(binders->get<CircleBlur>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders->get<CircleOpacity>()->interpolationFactor(zoom)),
/* .stroke_color_t = */
std::get<0>(binders->get<CircleStrokeColor>()->interpolationFactor(zoom)),
/* .stroke_width_t = */
std::get<0>(binders->get<CircleStrokeWidth>()->interpolationFactor(zoom)),
/* .stroke_opacity_t = */
std::get<0>(binders->get<CircleStrokeOpacity>()->interpolationFactor(zoom)),
/* .padding = */ 0};
drawableUniforms.createOrUpdate(idCircleInterpolateUBO, &interpolateUBO, context);
});
}

View File

@@ -6,14 +6,13 @@
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/programs/fill_extrusion_program.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/paint_property_binder.hpp>
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/std.hpp>
#if MLN_RENDER_BACKEND_METAL
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
@@ -62,11 +61,22 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
propertiesUpdated = false;
const auto zoom = static_cast<float>(parameters.state.getZoom());
const auto defPattern = mbgl::Faded<expression::Image>{"", ""};
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(defPattern);
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
return;
}
auto* binders = static_cast<FillExtrusionProgram::Binders*>(drawable.getBinders());
const auto* tile = drawable.getRenderTile();
if (!binders || !tile) {
assert(false);
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto& translation = evaluated.get<FillExtrusionTranslate>();
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
@@ -90,6 +100,13 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
textureSize = tex->getSize();
}
const auto hasPattern = !!drawable.getType();
const auto patternPosA = tile->getPattern(fillPatternValue.from.id());
const auto patternPosB = tile->getPattern(fillPatternValue.to.id());
if (hasPattern) {
binders->setPatternParameters(patternPosA, patternPosB, crossfade);
}
const FillExtrusionDrawableUBO drawableUBO = {
/* .matrix = */ util::cast<float>(matrix),
/* .texsize = */ {static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
@@ -98,8 +115,25 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
/* .height_factor = */ heightFactor,
/* .tile_ratio = */ tileRatio};
const FillExtrusionInterpolateUBO interpUBO = {
/* .base_t = */ std::get<0>(binders->get<FillExtrusionBase>()->interpolationFactor(zoom)),
/* .height_t = */ std::get<0>(binders->get<FillExtrusionHeight>()->interpolationFactor(zoom)),
/* .color_t = */ std::get<0>(binders->get<FillExtrusionColor>()->interpolationFactor(zoom)),
/* .pattern_from_t = */ std::get<0>(binders->get<FillExtrusionPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders->get<FillExtrusionPattern>()->interpolationFactor(zoom)),
/* .pad = */ 0,
0,
0};
const FillExtrusionTilePropsUBO tilePropsUBO = {
/* 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},
};
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idFillExtrusionDrawableUBO, &drawableUBO, context);
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
});
}

View File

@@ -6,6 +6,7 @@
#include <mbgl/gfx/renderer_backend.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/layers/render_fill_layer.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/paint_property_binder.hpp>
@@ -53,6 +54,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
const auto& translation = evaluated.get<FillTranslate>();
const auto anchor = evaluated.get<FillTranslateAnchor>();
const auto zoom = static_cast<float>(parameters.state.getZoom());
const auto intZoom = parameters.state.getIntegerZoom();
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
@@ -62,9 +64,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto* binders = static_cast<FillProgram::Binders*>(drawable.getBinders());
const auto* tile = drawable.getRenderTile();
if (!binders || !tile) {
assert(false);
return;
}
const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<expression::Image>{"", ""});
const auto patternPosA = tile->getPattern(fillPatternValue.from.id());
const auto patternPosB = tile->getPattern(fillPatternValue.to.id());
binders->setPatternParameters(patternPosA, patternPosB, crossfade);
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
constexpr bool nearClipped = false;
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
@@ -88,11 +101,27 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
case RenderFillLayer::FillVariant::Fill: {
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
const auto fillInterpolateUBO = FillInterpolateUBO{
/* .color_t = */ std::get<0>(binders->get<FillColor>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders->get<FillOpacity>()->interpolationFactor(zoom)),
0,
0,
};
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &fillInterpolateUBO, context);
break;
}
case RenderFillLayer::FillVariant::FillOutline: {
const FillOutlineDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
const auto fillOutlineInterpolateUBO = FillOutlineInterpolateUBO{
/* .color_t = */ std::get<0>(binders->get<FillOutlineColor>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders->get<FillOpacity>()->interpolationFactor(zoom)),
0,
0,
};
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &fillOutlineInterpolateUBO, context);
break;
}
case RenderFillLayer::FillVariant::FillPattern: {
@@ -105,6 +134,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
0,
};
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
const auto fillPatternInterpolateUBO = FillPatternInterpolateUBO{
/* .pattern_from_t = */ std::get<0>(binders->get<FillPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders->get<FillPattern>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders->get<FillOpacity>()->interpolationFactor(zoom)),
0,
};
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &fillPatternInterpolateUBO, context);
const auto fillPatternTilePropsUBO = FillPatternTilePropsUBO{
/* 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},
};
drawableUniforms.createOrUpdate(idFillTilePropsUBO, &fillPatternTilePropsUBO, context);
break;
}
case RenderFillLayer::FillVariant::FillOutlinePattern: {
@@ -116,6 +159,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
/*.tile_ratio = */ tileRatio,
0};
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
const auto fillOutlinePatternInterpolateUBO = FillPatternInterpolateUBO{
/* .pattern_from_t = */ std::get<0>(binders->get<FillPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders->get<FillPattern>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders->get<FillOpacity>()->interpolationFactor(zoom)),
0,
};
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &fillOutlinePatternInterpolateUBO, context);
const auto fillOutlinePatternTilePropsUBO = FillOutlinePatternTilePropsUBO{
/* 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},
};
drawableUniforms.createOrUpdate(idFillTilePropsUBO, &fillOutlinePatternTilePropsUBO, context);
break;
}
case RenderFillLayer::FillVariant::FillOutlineTriangulated: {

View File

@@ -2,6 +2,7 @@
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/programs/heatmap_program.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_static_data.hpp>
@@ -21,7 +22,7 @@ using namespace shaders;
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
auto& context = parameters.context;
const auto zoom = parameters.state.getZoom();
const auto zoom = static_cast<float>(parameters.state.getZoom());
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
if (layerGroup.empty()) {
@@ -52,17 +53,29 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamet
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto* binders = static_cast<HeatmapProgram::Binders*>(drawable.getBinders());
const auto* tile = drawable.getRenderTile();
if (!binders || !tile) {
assert(false);
return;
}
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, nearClipped, inViewportPixelUnits, drawable);
const HeatmapDrawableUBO drawableUBO = {
/* .matrix = */ util::cast<float>(matrix),
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
/* .padding = */ {0}};
const HeatmapDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, zoom),
/* .padding = */ {0}};
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idHeatmapDrawableUBO, &drawableUBO, context);
const HeatmapInterpolateUBO interpolateUBO = {
/* .weight_t = */ std::get<0>(binders->get<HeatmapWeight>()->interpolationFactor(zoom)),
/* .radius_t = */ std::get<0>(binders->get<HeatmapRadius>()->interpolationFactor(zoom)),
/* .padding = */ {0}};
drawableUniforms.createOrUpdate(idHeatmapInterpolateUBO, &interpolateUBO, context);
});
}

View File

@@ -4,13 +4,14 @@
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/line_drawable_data.hpp>
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/programs/line_program.hpp>
#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/shaders/line_layer_ubo.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/style/layers/line_layer_properties.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/math.hpp>
@@ -69,6 +70,8 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
const auto& crossfade = static_cast<const LineLayerProperties&>(*evaluatedProperties).crossfade;
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<expression::Image>{"", ""});
const auto zoom = static_cast<float>(parameters.state.getZoom());
const auto intZoom = parameters.state.getIntegerZoom();
@@ -160,17 +163,27 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
auto* binders = static_cast<LineProgram::Binders*>(drawable.getBinders());
const auto* tile = drawable.getRenderTile();
if (!binders || !tile) {
assert(false);
return;
}
const auto patternPosA = tile->getPattern(linePatternValue.from.id());
const auto patternPosB = tile->getPattern(linePatternValue.to.id());
binders->setPatternParameters(patternPosA, patternPosB, crossfade);
const auto& translation = evaluated.get<LineTranslate>();
const auto anchor = evaluated.get<LineTranslateAnchor>();
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
auto& drawableUniforms = drawable.mutableUniformBuffers();
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
const LineType type = static_cast<LineType>(drawable.getType());
switch (type) {
auto& drawableUniforms = drawable.mutableUniformBuffers();
switch (static_cast<LineType>(drawable.getType())) {
case LineType::Simple: {
const LineDrawableUBO drawableUBO = {
/*matrix = */ util::cast<float>(matrix),
@@ -179,6 +192,17 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
0,
0};
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
const auto lineInterpolationUBO = LineInterpolationUBO{
/*color_t =*/std::get<0>(binders->get<LineColor>()->interpolationFactor(zoom)),
/*blur_t =*/std::get<0>(binders->get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(binders->get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(binders->get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(binders->get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(binders->get<LineWidth>()->interpolationFactor(zoom)),
0,
0};
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &lineInterpolationUBO, context);
} break;
case LineType::Gradient: {
@@ -189,6 +213,17 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
0,
0};
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
const auto lineGradientInterpolationUBO = LineGradientInterpolationUBO{
/*blur_t =*/std::get<0>(binders->get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(binders->get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(binders->get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(binders->get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(binders->get<LineWidth>()->interpolationFactor(zoom)),
0,
0,
0};
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &lineGradientInterpolationUBO, context);
} break;
case LineType::Pattern: {
@@ -207,6 +242,22 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
/*ratio =*/1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
/*fade =*/crossfade.t};
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
const auto linePatternInterpolationUBO = LinePatternInterpolationUBO{
/*blur_t =*/std::get<0>(binders->get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(binders->get<LineOpacity>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(binders->get<LineOffset>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(binders->get<LineGapWidth>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(binders->get<LineWidth>()->interpolationFactor(zoom)),
/*pattern_from_t =*/std::get<0>(binders->get<LinePattern>()->interpolationFactor(zoom)),
/*pattern_to_t =*/std::get<1>(binders->get<LinePattern>()->interpolationFactor(zoom)),
0};
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &linePatternInterpolationUBO, context);
const auto linePatternTilePropertiesUBO = LinePatternTilePropertiesUBO{
/*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}};
drawableUniforms.createOrUpdate(idLineTilePropertiesUBO, &linePatternTilePropertiesUBO, context);
} break;
case LineType::SDF: {
@@ -246,13 +297,24 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
0,
0};
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
const auto lineSDFInterpolationUBO = LineSDFInterpolationUBO{
/*color_t =*/std::get<0>(binders->get<LineColor>()->interpolationFactor(zoom)),
/*blur_t =*/std::get<0>(binders->get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(binders->get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(binders->get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(binders->get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(binders->get<LineWidth>()->interpolationFactor(zoom)),
/*floorwidth_t =*/
std::get<0>(binders->get<LineFloorWidth>()->interpolationFactor(zoom)),
0};
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &lineSDFInterpolationUBO, context);
}
} break;
default: {
using namespace std::string_literals;
Log::Error(Event::General,
"LineLayerTweaker: unknown line type: "s + std::to_string(mbgl::underlying_type(type)));
"LineLayerTweaker: unknown line type: " + std::to_string(drawable.getType()));
} break;
}
});

View File

@@ -118,7 +118,7 @@ void RenderCircleLayer::render(PaintParameters& parameters) {
const auto& evaluated = getEvaluated<CircleLayerProperties>(data->layerProperties);
const bool scaleWithMap = evaluated.template get<CirclePitchScale>() == CirclePitchScaleType::Map;
const bool pitchWithMap = evaluated.template get<CirclePitchAlignment>() == AlignmentType::Map;
const auto& paintPropertyBinders = circleBucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = circleBucket.paintPropertyBinders.at(getID());
using LayoutUniformValues = CircleProgram::LayoutUniformValues;
const auto& allUniformValues = CircleProgram::computeAllUniformValues(
@@ -274,9 +274,9 @@ using namespace shaders;
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
[[maybe_unused]] const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
const TransformState&,
const std::shared_ptr<UpdateParameters>&,
const RenderTree&,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty()) {
removeAllDrawables();
@@ -327,9 +327,9 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto& bucket = static_cast<const CircleBucket&>(*renderData->bucket);
auto& bucket = static_cast<CircleBucket&>(*renderData->bucket);
const auto vertexCount = bucket.vertices.elements();
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -338,37 +338,18 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
}
setRenderTileBucketID(tileID, bucket.getID());
const float zoom = static_cast<float>(state.getZoom());
const CircleInterpolateUBO interpolateUBO = {
/* .color_t = */ std::get<0>(paintPropertyBinders.get<CircleColor>()->interpolationFactor(zoom)),
/* .radius_t = */ std::get<0>(paintPropertyBinders.get<CircleRadius>()->interpolationFactor(zoom)),
/* .blur_t = */ std::get<0>(paintPropertyBinders.get<CircleBlur>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(paintPropertyBinders.get<CircleOpacity>()->interpolationFactor(zoom)),
/* .stroke_color_t = */
std::get<0>(paintPropertyBinders.get<CircleStrokeColor>()->interpolationFactor(zoom)),
/* .stroke_width_t = */
std::get<0>(paintPropertyBinders.get<CircleStrokeWidth>()->interpolationFactor(zoom)),
/* .stroke_opacity_t = */
std::get<0>(paintPropertyBinders.get<CircleStrokeOpacity>()->interpolationFactor(zoom)),
/* .padding = */ 0};
// 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 false;
}
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idCircleInterpolateUBO, &interpolateUBO, context);
return true;
};
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
continue;
}
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
propertiesAsUniforms.first.clear();
propertiesAsUniforms.second.clear();
@@ -413,9 +394,8 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : circleBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& drawableUniforms = drawable->mutableUniformBuffers();
drawableUniforms.set(idCircleInterpolateUBO, interpBuffer);
drawable->setBinders(renderData->bucket, &paintPropertyBinders);
drawable->setRenderTile(renderTilesOwner, &tile);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;

View File

@@ -17,7 +17,6 @@
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/intersection_tests.hpp>
#include <mbgl/util/math.hpp>
@@ -112,13 +111,13 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
const auto& crossfade_,
const gfx::StencilMode& stencilMode,
const gfx::ColorMode& colorMode,
const auto& tileBucket,
auto& tileBucket,
const auto& uniformValues,
const std::optional<ImagePosition>& patternPositionA,
const std::optional<ImagePosition>& patternPositionB,
const auto& textureBindings,
const std::string& uniqueName) {
const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
const auto allUniformValues = programInstance.computeAllUniformValues(
@@ -152,7 +151,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
if (!renderData) {
continue;
}
const auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
draw(*fillExtrusionProgram,
evaluated,
crossfade,
@@ -200,7 +199,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
if (!renderData) {
continue;
}
const auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
const std::optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from.id());
const std::optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
const auto numTiles = std::pow(2, tile.id.canonical.z);
@@ -271,9 +270,9 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(const GeometryCoordinates&
void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const TransformState&,
const std::shared_ptr<UpdateParameters>&,
const RenderTree& /*renderTree*/,
const RenderTree&,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
removeAllDrawables();
@@ -304,7 +303,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
const auto& crossfade = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).crossfade;
// `passes` is set to (RenderPass::Translucent | RenderPass::Pass3D), but `render()`
// only runs on the translucent pass, so although our output is 3D, it does not render
@@ -320,7 +318,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
return false;
});
const auto zoom = static_cast<float>(state.getZoom());
const auto layerPrefix = getID() + "/";
const auto hasPattern = !unevaluated.get<FillExtrusionPattern>().isUndefined();
const auto opaque = evaluated.get<FillExtrusionOpacity>() >= 1;
@@ -347,7 +344,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
}
const auto& renderData = *optRenderData;
const auto& bucket = static_cast<const FillExtrusionBucket&>(*renderData.bucket);
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData.bucket);
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -365,30 +362,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
}
const auto vertexCount = bucket.vertices.elements();
const auto defPattern = mbgl::Faded<expression::Image>{"", ""};
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(defPattern);
const auto patternPosA = tile.getPattern(fillPatternValue.from.id());
const auto patternPosB = tile.getPattern(fillPatternValue.to.id());
const auto& binders = bucket.paintPropertyBinders.at(getID());
if (hasPattern) {
binders.setPatternParameters(patternPosA, patternPosB, crossfade);
}
const FillExtrusionInterpolateUBO interpUBO = {
/* .base_t = */ std::get<0>(binders.get<FillExtrusionBase>()->interpolationFactor(zoom)),
/* .height_t = */ std::get<0>(binders.get<FillExtrusionHeight>()->interpolationFactor(zoom)),
/* .color_t = */ std::get<0>(binders.get<FillExtrusionColor>()->interpolationFactor(zoom)),
/* .pattern_from_t = */ std::get<0>(binders.get<FillExtrusionPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders.get<FillExtrusionPattern>()->interpolationFactor(zoom)),
/* .pad = */ 0,
0,
0};
const FillExtrusionTilePropsUBO tilePropsUBO = {
/* 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},
};
auto& binders = bucket.paintPropertyBinders.at(getID());
// If we already have drawables for this tile, update them.
auto updateExisting = [&](gfx::Drawable& drawable) {
@@ -396,10 +370,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
// This drawable was produced on a previous style/bucket, and should not be updated.
return false;
}
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
return true;
};
if (updateTile(drawPass, tileID, std::move(updateExisting))) {
@@ -512,11 +482,10 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setType(static_cast<std::size_t>(hasPattern));
drawable->setLayerTweaker(layerTweaker);
auto& drawableUniforms = drawable->mutableUniformBuffers();
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
drawable->setBinders(renderData.bucket, &binders);
drawable->setRenderTile(renderTilesOwner, &tile);
tileLayerGroup->addDrawable(drawPass, tileID, std::move(drawable));
++stats.drawablesAdded;

View File

@@ -130,7 +130,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
const auto& indexBuffer,
const auto& segments,
auto&& textureBindings) {
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto allUniformValues = programInstance.computeAllUniformValues(
FillProgram::LayoutUniformValues{
@@ -214,7 +214,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
const auto& indexBuffer,
const auto& segments,
auto&& textureBindings) {
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
const auto allUniformValues = programInstance.computeAllUniformValues(
@@ -297,10 +297,10 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const TransformState&,
const std::shared_ptr<UpdateParameters>&,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
const RenderTree&,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty()) {
removeAllDrawables();
return;
@@ -376,7 +376,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
const auto& binders = bucket.paintPropertyBinders.at(getID());
auto& binders = bucket.paintPropertyBinders.at(getID());
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -386,95 +386,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
setRenderTileBucketID(tileID, bucket.getID());
const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
const auto& crossfade = getCrossfade<FillLayerProperties>(renderData->layerProperties);
const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<expression::Image>{"", ""});
const auto patternPosA = tile.getPattern(fillPatternValue.from.id());
const auto patternPosB = tile.getPattern(fillPatternValue.to.id());
binders.setPatternParameters(patternPosA, patternPosB, crossfade);
const auto zoom = static_cast<float>(state.getZoom());
std::optional<FillInterpolateUBO> fillInterpolateUBO = std::nullopt;
std::optional<FillOutlineInterpolateUBO> fillOutlineInterpolateUBO = std::nullopt;
std::optional<FillPatternInterpolateUBO> fillPatternInterpolateUBO = std::nullopt;
std::optional<FillOutlinePatternInterpolateUBO> fillOutlinePatternInterpolateUBO = std::nullopt;
auto getFillInterpolateUBO = [&]() -> const FillInterpolateUBO& {
if (!fillInterpolateUBO) {
fillInterpolateUBO = {
/* .color_t = */ std::get<0>(binders.get<FillColor>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders.get<FillOpacity>()->interpolationFactor(zoom)),
0,
0,
};
}
return *fillInterpolateUBO;
};
auto getFillOutlineInterpolateUBO = [&]() -> const FillOutlineInterpolateUBO& {
if (!fillOutlineInterpolateUBO) {
fillOutlineInterpolateUBO = {
/* .color_t = */ std::get<0>(binders.get<FillOutlineColor>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders.get<FillOpacity>()->interpolationFactor(zoom)),
0,
0,
};
}
return *fillOutlineInterpolateUBO;
};
auto getFillPatternInterpolateUBO = [&]() -> const FillPatternInterpolateUBO& {
if (!fillPatternInterpolateUBO) {
fillPatternInterpolateUBO = {
/* .pattern_from_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders.get<FillOpacity>()->interpolationFactor(zoom)),
0,
};
}
return *fillPatternInterpolateUBO;
};
auto getFillOutlinePatternInterpolateUBO = [&]() -> const FillOutlinePatternInterpolateUBO& {
if (!fillOutlinePatternInterpolateUBO) {
fillOutlinePatternInterpolateUBO = {
/* .pattern_from_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
/* .pattern_to_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
/* .opacity_t = */ std::get<0>(binders.get<FillOpacity>()->interpolationFactor(zoom)),
0,
};
}
return *fillOutlinePatternInterpolateUBO;
};
std::optional<FillPatternTilePropsUBO> fillPatternTilePropsUBO = std::nullopt;
auto getFillPatternTilePropsUBO = [&]() -> const FillPatternTilePropsUBO& {
if (!fillPatternTilePropsUBO) {
fillPatternTilePropsUBO = {
/* 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},
};
}
return *fillPatternTilePropsUBO;
};
std::optional<FillOutlinePatternTilePropsUBO> fillOutlinePatternTilePropsUBO = std::nullopt;
auto getFillOutlinePatternTilePropsUBO = [&]() -> const FillOutlinePatternTilePropsUBO& {
if (!fillOutlinePatternTilePropsUBO) {
fillOutlinePatternTilePropsUBO = {
/* 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},
};
}
return *fillOutlinePatternTilePropsUBO;
};
gfx::DrawableTweakerPtr atlasTweaker;
auto getAtlasTweaker = [&]() {
@@ -498,6 +409,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
propertiesAsUniforms.second.clear();
// `Fill*Program` all use `style::FillPaintProperties`
// TODO: Only rebuild the vertex attributes when something has changed.
// TODO: Can we update them in-place instead of replacing?
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
binders, evaluated, propertiesAsUniforms, idFillColorVertexAttribute);
@@ -513,38 +426,10 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
// If we already have drawables for this tile, update them.
auto updateExisting = [&](gfx::Drawable& drawable) {
auto& drawableUniforms = drawable.mutableUniformBuffers();
switch (static_cast<FillVariant>(drawable.getType())) {
case FillVariant::Fill: {
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &getFillInterpolateUBO(), context);
break;
}
case FillVariant::FillOutline: {
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &getFillOutlineInterpolateUBO(), context);
break;
}
case FillVariant::FillPattern: {
drawableUniforms.createOrUpdate(idFillInterpolateUBO, &getFillPatternInterpolateUBO(), context);
drawableUniforms.createOrUpdate(idFillTilePropsUBO, &getFillPatternTilePropsUBO(), context);
break;
}
case FillVariant::FillOutlinePattern: {
drawableUniforms.createOrUpdate(
idFillInterpolateUBO, &getFillOutlinePatternInterpolateUBO(), context);
drawableUniforms.createOrUpdate(idFillTilePropsUBO, &getFillOutlinePatternTilePropsUBO(), context);
break;
}
case FillVariant::FillOutlineTriangulated: {
break;
}
default: {
#ifndef NDEBUG
mbgl::Log::Error(mbgl::Event::Render, "Invalid fill variant type supplied during drawable update!");
#endif
break;
}
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return false;
}
drawable.setVertexAttributes(vertexAttrs);
return true;
};
@@ -552,6 +437,16 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto addDrawable = [&](std::unique_ptr<gfx::Drawable> drawable, FillVariant type) {
drawable->setTileID(tileID);
drawable->setType(static_cast<size_t>(type));
drawable->setLayerTweaker(layerTweaker);
drawable->setBinders(renderData->bucket, &binders);
drawable->setRenderTile(renderTilesOwner, &tile);
fillTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
};
// Outline always occurs in translucent pass, defaults to fill color
// Outline does not default to fill in the pattern case
const auto doOutline = evaluated.get<FillAntialias>() && (unevaluated.get<FillPattern>().isUndefined() ||
@@ -606,13 +501,9 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.lineSegments.data(),
bucket.lineSegments.size());
// finish
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setType(static_cast<size_t>(FillVariant::FillOutlineTriangulated));
fillTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), FillVariant::FillOutlineTriangulated);
}
}
};
@@ -648,21 +539,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
}
const auto finish = [&](gfx::DrawableBuilder& builder,
const size_t interpolateUBOId,
const auto& interpolateUBO,
FillVariant type) {
const auto finish = [&](gfx::DrawableBuilder& builder, FillVariant type) {
builder.flush(context);
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->setType(static_cast<size_t>(type));
auto& drawableUniforms = drawable->mutableUniformBuffers();
drawableUniforms.createOrUpdate(interpolateUBOId, &interpolateUBO, context);
fillTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), type);
}
};
@@ -688,7 +569,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.sharedTriangles,
bucket.triangleSegments.data(),
bucket.triangleSegments.size());
finish(*fillBuilder, idFillInterpolateUBO, getFillInterpolateUBO(), FillVariant::Fill);
finish(*fillBuilder, FillVariant::Fill);
}
#if MLN_TRIANGULATE_FILL_OUTLINES
@@ -704,8 +585,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.sharedBasicLineIndexes,
bucket.basicLineSegments.data(),
bucket.basicLineSegments.size());
finish(
*outlineBuilder, idFillInterpolateUBO, getFillInterpolateUBO(), FillVariant::FillOutline);
finish(*outlineBuilder, FillVariant::FillOutline);
}
}
}
@@ -717,7 +597,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.sharedBasicLineIndexes,
bucket.basicLineSegments.data(),
bucket.basicLineSegments.size());
finish(*outlineBuilder, idFillInterpolateUBO, getFillOutlineInterpolateUBO(), FillVariant::FillOutline);
finish(*outlineBuilder, FillVariant::FillOutline);
}
#endif
} else {
@@ -770,24 +650,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
outlinePatternBuilder->addTweaker(getAtlasTweaker());
}
const auto finish = [&](gfx::DrawableBuilder& builder,
const size_t interpolateNameId,
const auto& interpolateUBO,
const size_t tileUBOId,
const auto& tileUBO,
FillVariant type) {
const auto finish = [&](gfx::DrawableBuilder& builder, FillVariant type) {
builder.flush(context);
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->setType(static_cast<size_t>(type));
auto& drawableUniforms = drawable->mutableUniformBuffers();
drawableUniforms.createOrUpdate(interpolateNameId, &interpolateUBO, context);
drawableUniforms.createOrUpdate(tileUBOId, &tileUBO, context);
fillTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), type);
}
};
@@ -806,12 +673,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.triangleSegments.data(),
bucket.triangleSegments.size());
finish(*patternBuilder,
idFillInterpolateUBO,
getFillPatternInterpolateUBO(),
idFillTilePropsUBO,
getFillPatternTilePropsUBO(),
FillVariant::FillPattern);
finish(*patternBuilder, FillVariant::FillPattern);
}
if (doOutline && outlinePatternBuilder && bucket.sharedBasicLineIndexes->elements()) {
@@ -823,12 +685,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
bucket.basicLineSegments.data(),
bucket.basicLineSegments.size());
finish(*outlinePatternBuilder,
idFillInterpolateUBO,
getFillOutlinePatternInterpolateUBO(),
idFillTilePropsUBO,
getFillOutlinePatternTilePropsUBO(),
FillVariant::FillOutlinePattern);
finish(*outlinePatternBuilder, FillVariant::FillOutlinePattern);
}
}
}

View File

@@ -130,7 +130,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters) {
const auto extrudeScale = tile.id.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom()));
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto allUniformValues = HeatmapProgram::computeAllUniformValues(
HeatmapProgram::LayoutUniformValues{
@@ -361,9 +361,9 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
const auto vertexCount = bucket.vertices.elements();
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -372,37 +372,14 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
setRenderTileBucketID(tileID, bucket.getID());
const float zoom = static_cast<float>(state.getZoom());
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), false);
}
return interpolateBuffer;
};
const auto updatedCount = tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return;
return false;
}
// We assume vertex attributes don't change, and so don't update them to avoid re-uploading
// drawable.setVertexAttributes(heatmapVertexAttrs);
auto& drawableUniforms = drawable.mutableUniformBuffers();
if (auto buffer = getInterpolateBuffer()) {
drawableUniforms.set(idHeatmapInterpolateUBO, std::move(buffer));
}
});
if (updatedCount > 0) {
return true;
};
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
continue;
}
@@ -460,13 +437,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
for (auto& drawable : heatmapBuilder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
auto& drawableUniforms = drawable->mutableUniformBuffers();
if (auto buffer = getInterpolateBuffer()) {
drawableUniforms.set(idHeatmapInterpolateUBO, std::move(buffer));
}
drawable->setBinders(renderData->bucket, &paintPropertyBinders);
drawable->setRenderTile(renderTilesOwner, &tile);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
}

View File

@@ -157,7 +157,7 @@ void RenderLineLayer::render(PaintParameters& parameters) {
const std::optional<ImagePosition>& patternPositionA,
const std::optional<ImagePosition>& patternPositionB,
auto&& textureBindings) {
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade);
@@ -355,12 +355,20 @@ float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature,
}
#if MLN_DRAWABLE_RENDERER
namespace {
inline void setSegments(std::unique_ptr<gfx::DrawableBuilder>& builder, const LineBucket& bucket) {
builder->setSegments(gfx::Triangles(), bucket.sharedTriangles, bucket.segments.data(), bucket.segments.size());
}
} // namespace
void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const TransformState&,
[[maybe_unused]] const std::shared_ptr<UpdateParameters>& parameters,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
const RenderTree&,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty()) {
removeAllDrawables();
return;
@@ -437,10 +445,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
builder.setVertexAttributes(std::move(vertexAttrs));
};
auto setSegments = [&](std::unique_ptr<gfx::DrawableBuilder>& builder, const LineBucket& bucket) {
builder->setSegments(gfx::Triangles(), bucket.sharedTriangles, bucket.segments.data(), bucket.segments.size());
};
tileLayerGroup->setStencilTiles(renderTiles);
StringIDSetsPair propertiesAsUniforms;
@@ -459,9 +463,8 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
const auto& crossfade = getCrossfade<LineLayerProperties>(renderData->layerProperties);
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -470,137 +473,32 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
}
setRenderTileBucketID(tileID, bucket.getID());
// interpolation UBOs
const float zoom = static_cast<float>(state.getZoom());
std::optional<LineInterpolationUBO> lineInterpolationUBO = std::nullopt;
std::optional<LineGradientInterpolationUBO> lineGradientInterpolationUBO = std::nullopt;
std::optional<LinePatternInterpolationUBO> linePatternInterpolationUBO = std::nullopt;
std::optional<LineSDFInterpolationUBO> lineSDFInterpolationUBO = std::nullopt;
auto getLineInterpolationUBO = [&]() -> const LineInterpolationUBO& {
if (!lineInterpolationUBO) {
lineInterpolationUBO = {
/*color_t =*/std::get<0>(paintPropertyBinders.get<LineColor>()->interpolationFactor(zoom)),
/*blur_t =*/std::get<0>(paintPropertyBinders.get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(paintPropertyBinders.get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(paintPropertyBinders.get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(paintPropertyBinders.get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(paintPropertyBinders.get<LineWidth>()->interpolationFactor(zoom)),
0,
0};
}
return *lineInterpolationUBO;
};
auto getLineGradientInterpolationUBO = [&]() -> const LineGradientInterpolationUBO& {
if (!lineGradientInterpolationUBO) {
lineGradientInterpolationUBO = {
/*blur_t =*/std::get<0>(paintPropertyBinders.get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(paintPropertyBinders.get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(paintPropertyBinders.get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(paintPropertyBinders.get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(paintPropertyBinders.get<LineWidth>()->interpolationFactor(zoom)),
0,
0,
0};
}
return *lineGradientInterpolationUBO;
};
auto getLinePatternInterpolationUBO = [&]() -> const LinePatternInterpolationUBO& {
if (!linePatternInterpolationUBO) {
linePatternInterpolationUBO = {
/*blur_t =*/std::get<0>(paintPropertyBinders.get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(paintPropertyBinders.get<LineOpacity>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(paintPropertyBinders.get<LineOffset>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(paintPropertyBinders.get<LineGapWidth>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(paintPropertyBinders.get<LineWidth>()->interpolationFactor(zoom)),
/*pattern_from_t =*/std::get<0>(paintPropertyBinders.get<LinePattern>()->interpolationFactor(zoom)),
/*pattern_to_t =*/std::get<1>(paintPropertyBinders.get<LinePattern>()->interpolationFactor(zoom)),
0};
}
return *linePatternInterpolationUBO;
};
auto getLineSDFInterpolationUBO = [&]() -> const LineSDFInterpolationUBO& {
if (!lineSDFInterpolationUBO) {
lineSDFInterpolationUBO = {
/*color_t =*/std::get<0>(paintPropertyBinders.get<LineColor>()->interpolationFactor(zoom)),
/*blur_t =*/std::get<0>(paintPropertyBinders.get<LineBlur>()->interpolationFactor(zoom)),
/*opacity_t =*/std::get<0>(paintPropertyBinders.get<LineOpacity>()->interpolationFactor(zoom)),
/*gapwidth_t =*/std::get<0>(paintPropertyBinders.get<LineGapWidth>()->interpolationFactor(zoom)),
/*offset_t =*/std::get<0>(paintPropertyBinders.get<LineOffset>()->interpolationFactor(zoom)),
/*width_t =*/std::get<0>(paintPropertyBinders.get<LineWidth>()->interpolationFactor(zoom)),
/*floorwidth_t =*/
std::get<0>(paintPropertyBinders.get<LineFloorWidth>()->interpolationFactor(zoom)),
0};
}
return *lineSDFInterpolationUBO;
};
// tile dependent properties UBOs:
std::optional<LinePatternTilePropertiesUBO> linePatternTilePropertiesUBO = std::nullopt;
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<expression::Image>{"", ""});
const std::optional<ImagePosition> patternPosA = tile.getPattern(linePatternValue.from.id());
const std::optional<ImagePosition> patternPosB = tile.getPattern(linePatternValue.to.id());
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
auto getLinePatternTilePropertiesUBO = [&]() -> const LinePatternTilePropertiesUBO& {
if (!linePatternTilePropertiesUBO) {
linePatternTilePropertiesUBO = {
/*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}};
}
return *linePatternTilePropertiesUBO;
};
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
return false;
}
auto& drawableUniforms = drawable.mutableUniformBuffers();
const LineLayerTweaker::LineType type = static_cast<LineLayerTweaker::LineType>(drawable.getType());
switch (type) {
case LineLayerTweaker::LineType::Simple: {
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &getLineInterpolationUBO(), context);
} break;
case LineLayerTweaker::LineType::Gradient: {
drawableUniforms.createOrUpdate(
idLineInterpolationUBO, &getLineGradientInterpolationUBO(), context);
} break;
case LineLayerTweaker::LineType::Pattern: {
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &getLinePatternInterpolationUBO(), context);
drawableUniforms.createOrUpdate(
idLineTilePropertiesUBO, &getLinePatternTilePropertiesUBO(), context);
} break;
case LineLayerTweaker::LineType::SDF: {
drawableUniforms.createOrUpdate(idLineInterpolationUBO, &getLineSDFInterpolationUBO(), context);
} break;
default: {
using namespace std::string_literals;
Log::Error(Event::General,
"RenderLineLayer: unknown line type: "s + std::to_string(mbgl::underlying_type(type)));
} break;
}
return true;
};
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
continue;
}
const auto addDrawable = [&](std::unique_ptr<gfx::Drawable>&& drawable, LineLayerTweaker::LineType type) {
drawable->setTileID(tileID);
drawable->setType(mbgl::underlying_type(type));
drawable->setLayerTweaker(layerTweaker);
drawable->setRenderTile(renderTilesOwner, &tile);
drawable->setBinders(renderData->bucket, &paintPropertyBinders);
const bool roundCap = bucket.layout.get<LineCap>() == LineCapType::Round;
const auto capType = roundCap ? LinePatternCap::Round : LinePatternCap::Square;
drawable->setData(std::make_unique<gfx::LineDrawableData>(capType));
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
};
propertiesAsUniforms.first.clear();
propertiesAsUniforms.second.clear();
@@ -635,20 +533,9 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
addAttributes(*builder, bucket, std::move(vertexAttrs));
setSegments(builder, bucket);
// finish
builder->flush(context);
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round
: LinePatternCap::Square;
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(
idLineInterpolationUBO, &getLineSDFInterpolationUBO(), context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), LineLayerTweaker::LineType::SDF);
}
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
// pattern line
@@ -689,16 +576,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineInterpolationUBO, &getLinePatternInterpolationUBO(), context);
drawable->mutableUniformBuffers().createOrUpdate(
idLineTilePropertiesUBO, &getLinePatternTilePropertiesUBO(), context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), LineLayerTweaker::LineType::Pattern);
}
}
} else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) {
@@ -733,20 +611,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
if (colorRampTexture2D) {
builder->setTexture(colorRampTexture2D, idLineImageTexture);
// segments
setSegments(builder, bucket);
// finish
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineInterpolationUBO, &getLineGradientInterpolationUBO(), context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), LineLayerTweaker::LineType::Gradient);
}
}
} else {
@@ -769,17 +638,9 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
addAttributes(*builder, bucket, std::move(vertexAttrs));
setSegments(builder, bucket);
// finish
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->mutableUniformBuffers().createOrUpdate(
idLineInterpolationUBO, &getLineInterpolationUBO(), context);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.drawablesAdded;
addDrawable(std::move(drawable), LineLayerTweaker::LineType::Simple);
}
}
}

View File

@@ -725,49 +725,8 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
#if MLN_DRAWABLE_RENDERER
namespace {
const SegmentVector<SymbolTextAttributes> emptySegmentVector;
template <typename TText, typename TIcon>
const auto& getProperty(const SymbolBucket::PaintProperties& paintProps, bool isText) {
return isText ? paintProps.textBinders.get<TText>() : paintProps.iconBinders.get<TIcon>();
}
template <typename TText, typename TIcon, std::size_t N>
auto getInterpFactor(const SymbolBucket::PaintProperties& paintProps, bool isText, float currentZoom) {
return std::get<N>(getProperty<TText, TIcon>(paintProps, isText)->interpolationFactor(currentZoom));
}
SymbolInterpolateUBO buildInterpUBO(const SymbolBucket::PaintProperties& paint, const bool t, const float z) {
return {/* .fill_color_t = */ getInterpFactor<TextColor, IconColor, 0>(paint, t, z),
/* .halo_color_t = */ getInterpFactor<TextHaloColor, IconHaloColor, 0>(paint, t, z),
/* .opacity_t = */ getInterpFactor<TextOpacity, IconOpacity, 0>(paint, t, z),
/* .halo_width_t = */ getInterpFactor<TextHaloWidth, IconHaloWidth, 0>(paint, t, z),
/* .halo_blur_t = */ getInterpFactor<TextHaloBlur, IconHaloBlur, 0>(paint, t, z),
/* .padding = */ 0,
0,
0};
}
SymbolTilePropsUBO buildTileUBO(const SymbolBucket& bucket,
const gfx::SymbolDrawableData& drawData,
const float currentZoom) {
const bool isText = (drawData.symbolType == SymbolType::Text);
const ZoomEvaluatedSize size = isText ? bucket.textSizeBinder->evaluateForZoom(currentZoom)
: bucket.iconSizeBinder->evaluateForZoom(currentZoom);
return {
/* .is_text = */ isText,
/* .is_halo = */ drawData.isHalo,
/* .pitch_with_map = */ (drawData.pitchAlignment == style::AlignmentType::Map),
/* .is_size_zoom_constant = */ size.isZoomConstant,
/* .is_size_feature_constant = */ size.isFeatureConstant,
/* .size_t = */ size.sizeT,
/* .size = */ size.size,
/* .padding = */ 0,
};
}
const auto posOffsetAttribName = "a_pos_offset";
constexpr auto posOffsetAttribName = "a_pos_offset";
void updateTileAttributes(const SymbolBucket::Buffer& buffer,
const bool isText,
@@ -824,13 +783,9 @@ void updateTileAttributes(const SymbolBucket::Buffer& buffer,
}
void updateTileDrawable(gfx::Drawable& drawable,
gfx::Context& context,
const SymbolBucket& bucket,
const SymbolBucket::PaintProperties& paintProps,
const SymbolPaintProperties::PossiblyEvaluated& evaluated,
const TransformState& state,
gfx::UniformBufferPtr& textInterpUBO,
gfx::UniformBufferPtr& iconInterpUBO) {
const SymbolPaintProperties::PossiblyEvaluated& evaluated) {
if (!drawable.getData()) {
return;
}
@@ -838,31 +793,10 @@ void updateTileDrawable(gfx::Drawable& drawable,
auto& drawData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
const auto isText = (drawData.symbolType == SymbolType::Text);
const auto sdfIcons = (drawData.symbolType == SymbolType::IconSDF);
const auto currentZoom = static_cast<float>(state.getZoom());
// This property can be set after the initial appearance of the tile, as part of the layout process.
drawData.bucketVariablePlacement = bucket.hasVariablePlacement;
auto& drawableUniforms = drawable.mutableUniformBuffers();
// Create or update the shared interpolation UBO
gfx::UniformBufferPtr& interpUBO = isText ? textInterpUBO : iconInterpUBO;
if (interpUBO) {
drawableUniforms.set(idSymbolInterpolateUBO, interpUBO);
} else {
const auto ubo = buildInterpUBO(paintProps, isText, currentZoom);
interpUBO = drawableUniforms.get(idSymbolInterpolateUBO);
if (interpUBO) {
interpUBO->update(&ubo, sizeof(ubo));
} else {
interpUBO = context.createUniformBuffer(&ubo, sizeof(ubo));
drawableUniforms.set(idSymbolInterpolateUBO, interpUBO);
}
}
const auto tileUBO = buildTileUBO(bucket, drawData, currentZoom);
drawableUniforms.createOrUpdate(idSymbolTilePropsUBO, &tileUBO, context);
const auto& buffer = isText ? bucket.text : (sdfIcons ? bucket.sdfIcon : bucket.icon);
const auto vertexCount = buffer.vertices().elements();
@@ -973,7 +907,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const RenderTree& /*renderTree*/,
const RenderTree&,
UniqueChangeRequestVec& changes) {
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
removeAllDrawables();
@@ -1071,6 +1005,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto& renderData = *optRenderData;
const auto& bucket = static_cast<const SymbolBucket&>(*renderData.bucket);
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
const auto prevBucketID = getRenderTileBucketID(tileID);
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
@@ -1091,11 +1026,10 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
}
const auto& layout = *bucket.layout;
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout);
const std::string suffix = isText ? "text/" : "icon/";
auto addVertices = [&collisionBuilder](const auto& vertices) {
const auto addVertices = [&collisionBuilder](const auto& vertices) {
collisionBuilder->setRawVertices({}, vertices.size(), gfx::AttributeDataType::Short2);
};
@@ -1145,7 +1079,6 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
// If we already have drawables for this tile, update them.
// Just update the drawables we already created
gfx::UniformBufferPtr textInterpUBO, iconInterpUBO;
auto updateExisting = [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
@@ -1155,9 +1088,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
propertiesAsUniforms.first.clear();
propertiesAsUniforms.second.clear();
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
updateTileDrawable(
drawable, context, bucket, bucketPaintProperties, evaluated, state, textInterpUBO, iconInterpUBO);
updateTileDrawable(drawable, bucket, bucketPaintProperties, evaluated);
return true;
};
if (updateTile(passes, tileID, std::move(updateExisting))) {
@@ -1216,10 +1147,9 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
struct TileInfo {
RawVertexVec textVertices, iconVertices;
gfx::DrawableTweakerPtr textTweaker, iconTweaker;
gfx::UniformBufferPtr textInterp, iconInterp;
};
std::unordered_map<UnwrappedTileID, TileInfo> tileCache;
mbgl::unordered_map<UnwrappedTileID, TileInfo> tileCache;
tileCache.reserve(renderTiles->size());
for (auto& group : renderableSegments) {
@@ -1231,7 +1161,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto& tile = renderable.tile;
const auto tileID = tile.id.overscaleTo(renderable.overscaledZ);
const auto& bucket = static_cast<const SymbolBucket&>(*renderable.renderData.bucket);
auto& bucket = static_cast<SymbolBucket&>(*renderable.renderData.bucket);
const auto& buffer = isText ? bucket.text : (sdfIcons ? bucket.sdfIcon : bucket.icon);
if (!buffer.sharedTriangles->elements()) {
@@ -1239,7 +1169,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
}
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderable.renderData.layerProperties);
const auto& bucketPaintProperties = bucket.paintProperties.at(getID());
auto& bucketPaintProperties = bucket.paintProperties.at(getID());
const auto& layout = *bucket.layout;
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout);
@@ -1268,105 +1198,97 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
evaluated.get<style::IconHaloWidth>().constantOr(1);
const auto iconFill = evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0.0f;
// Share interpolation UBOs across all the elements of the same type in each tile
auto& interpUBO = isText ? tileInfo.textInterp : tileInfo.iconInterp;
if (!interpUBO) {
const auto interpolateBuf = buildInterpUBO(bucketPaintProperties, isText, currentZoom);
interpUBO = context.createUniformBuffer(&interpolateBuf, sizeof(interpolateBuf));
}
if (builder) {
builder->clearTweakers();
}
const auto draw =
[&](const gfx::ShaderGroupPtr& shaderGroup, const bool isHalo, const std::string_view suffix) {
if (!shaderGroup) {
return;
}
const auto draw = [&](const gfx::ShaderGroupPtr& shaderGroup,
const bool isHalo,
const std::string_view suffix) {
if (!shaderGroup) {
return;
}
// We can use the same tweakers for all the segments in a tile
if (isText && !tileInfo.textTweaker) {
const bool textSizeIsZoomConstant =
bucket.textSizeBinder->evaluateForZoom(static_cast<float>(state.getZoom())).isZoomConstant;
tileInfo.textTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
idSymbolImageIconTexture,
idSymbolImageTexture,
isText,
false,
values.rotationAlignment,
false,
textSizeIsZoomConstant);
}
if (!isText && !tileInfo.iconTweaker) {
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
tileInfo.iconTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
idSymbolImageIconTexture,
idSymbolImageTexture,
isText,
sdfIcons,
values.rotationAlignment,
iconScaled,
false);
}
// We can use the same tweakers for all the segments in a tile
if (isText && !tileInfo.textTweaker) {
const bool textSizeIsZoomConstant = bucket.textSizeBinder->evaluateForZoom(currentZoom).isZoomConstant;
tileInfo.textTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
idSymbolImageIconTexture,
idSymbolImageTexture,
isText,
false,
values.rotationAlignment,
false,
textSizeIsZoomConstant);
}
if (!isText && !tileInfo.iconTweaker) {
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
tileInfo.iconTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
idSymbolImageIconTexture,
idSymbolImageTexture,
isText,
sdfIcons,
values.rotationAlignment,
iconScaled,
false);
}
if (!builder) {
builder = context.createDrawableBuilder(layerPrefix);
builder->setSubLayerIndex(0);
builder->setRenderPass(passes);
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setColorMode(
((mbgl::underlying_type(passes) & mbgl::underlying_type(RenderPass::Translucent)) != 0)
? gfx::ColorMode::alphaBlended()
: gfx::ColorMode::unblended());
}
if (!builder) {
builder = context.createDrawableBuilder(layerPrefix);
builder->setSubLayerIndex(0);
builder->setRenderPass(passes);
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
builder->setColorMode(
((mbgl::underlying_type(passes) & mbgl::underlying_type(RenderPass::Translucent)) != 0)
? gfx::ColorMode::alphaBlended()
: gfx::ColorMode::unblended());
}
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
if (!shader) {
return;
}
builder->setShader(shader);
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
if (!shader) {
return;
}
builder->setShader(shader);
builder->clearTweakers();
builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker);
builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4);
builder->setDrawableName(layerPrefix + std::string(suffix));
builder->setVertexAttributes(attribs);
builder->clearTweakers();
builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker);
builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4);
builder->setDrawableName(layerPrefix + std::string(suffix));
builder->setVertexAttributes(attribs);
if (segments.empty()) {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
} else {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, segments.data(), segments.size());
}
if (segments.empty()) {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
} else {
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, segments.data(), segments.size());
}
builder->flush(context);
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);
drawable->setRenderTile(renderTilesOwner, &tile);
auto drawData = std::make_unique<gfx::SymbolDrawableData>(
/*.isHalo=*/isHalo,
/*.bucketVariablePlacement=*/bucket.hasVariablePlacement,
/*.symbolType=*/renderable.type,
/*.pitchAlignment=*/values.pitchAlignment,
/*.rotationAlignment=*/values.rotationAlignment,
/*.placement=*/layout.get<SymbolPlacement>(),
/*.textFit=*/layout.get<IconTextFit>());
PaintPropertyBindersBase& textBinders = bucketPaintProperties.textBinders;
PaintPropertyBindersBase& iconBinders = bucketPaintProperties.iconBinders;
drawable->setBinders(renderable.renderData.bucket, isText ? &textBinders : &iconBinders);
const auto tileUBO = buildTileUBO(bucket, *drawData, currentZoom);
drawable->setData(std::move(drawData));
const bool hasVariablePlacement = bucket.hasVariablePlacement;
drawable->setData(std::make_unique<gfx::SymbolDrawableData>(
/*.isHalo=*/isHalo,
/*.bucketVaraiblePlacement=*/hasVariablePlacement,
/*.symbolType=*/renderable.type,
/*.pitchAlignment=*/values.pitchAlignment,
/*.rotationAlignment=*/values.rotationAlignment,
/*.placement=*/layout.get<SymbolPlacement>(),
/*.textFit=*/layout.get<IconTextFit>()));
auto& drawableUniforms = drawable->mutableUniformBuffers();
drawableUniforms.createOrUpdate(idSymbolTilePropsUBO, &tileUBO, context);
drawableUniforms.set(idSymbolInterpolateUBO, interpUBO);
tileLayerGroup->addDrawable(passes, tileID, std::move(drawable));
++stats.drawablesAdded;
}
};
tileLayerGroup->addDrawable(passes, tileID, std::move(drawable));
++stats.drawablesAdded;
}
};
if (isText) {
if (bucket.iconsInText) {

View File

@@ -7,10 +7,11 @@
#include <mbgl/gfx/symbol_drawable_data.hpp>
#include <mbgl/layout/symbol_projection.hpp>
#include <mbgl/programs/symbol_program.hpp>
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/paint_property_binder.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/shaders/symbol_layer_ubo.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
@@ -40,6 +41,27 @@ std::array<float, 2> toArray(const Size& s) {
return util::cast<float>(std::array<uint32_t, 2>{s.width, s.height});
}
template <typename TText, typename TIcon>
const auto& getProperty(const SymbolBucket::PaintProperties& paintProps, bool isText) {
return isText ? paintProps.textBinders.get<TText>() : paintProps.iconBinders.get<TIcon>();
}
template <typename TText, typename TIcon, std::size_t N>
auto getInterpFactor(const SymbolBucket::PaintProperties& paintProps, bool isText, float currentZoom) {
return std::get<N>(getProperty<TText, TIcon>(paintProps, isText)->interpolationFactor(currentZoom));
}
SymbolInterpolateUBO buildInterpUBO(const SymbolBucket::PaintProperties& paint, const bool t, const float z) {
return {/* .fill_color_t = */ getInterpFactor<TextColor, IconColor, 0>(paint, t, z),
/* .halo_color_t = */ getInterpFactor<TextHaloColor, IconHaloColor, 0>(paint, t, z),
/* .opacity_t = */ getInterpFactor<TextOpacity, IconOpacity, 0>(paint, t, z),
/* .halo_width_t = */ getInterpFactor<TextHaloWidth, IconHaloWidth, 0>(paint, t, z),
/* .halo_blur_t = */ getInterpFactor<TextHaloBlur, IconHaloBlur, 0>(paint, t, z),
/* .padding = */ 0,
0,
0};
}
} // namespace
void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
@@ -56,25 +78,44 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
#endif
const auto zoom = static_cast<float>(state.getZoom());
if (!evaluatedPropsUniformBuffer || propertiesUpdated) {
const SymbolEvaluatedPropsUBO propsUBO = {/*.text_fill_color=*/constOrDefault<TextColor>(evaluated),
/*.text_halo_color=*/constOrDefault<TextHaloColor>(evaluated),
/*.text_opacity=*/constOrDefault<TextOpacity>(evaluated),
/*.text_halo_width=*/constOrDefault<TextHaloWidth>(evaluated),
/*.text_halo_blur=*/constOrDefault<TextHaloBlur>(evaluated),
0,
/* pad */ 0,
/*.icon_fill_color=*/constOrDefault<IconColor>(evaluated),
/*.icon_halo_color=*/constOrDefault<IconHaloColor>(evaluated),
/*.icon_opacity=*/constOrDefault<IconOpacity>(evaluated),
/*.icon_halo_width=*/constOrDefault<IconHaloWidth>(evaluated),
/*.icon_halo_blur=*/constOrDefault<IconHaloBlur>(evaluated),
0};
/* pad */ 0};
context.emplaceOrUpdateUniformBuffer(evaluatedPropsUniformBuffer, &propsUBO);
propertiesUpdated = false;
}
auto& layerUniforms = layerGroup.mutableUniformBuffers();
layerUniforms.set(idSymbolEvaluatedPropsUBO, evaluatedPropsUniformBuffer);
const auto getInterpUBO =
[&](const UnwrappedTileID& tileID, bool isText, const SymbolBucket::PaintProperties& paintProps) {
auto result = interpUBOs.insert(
std::make_pair(InterpUBOKey{tileID, isText}, InterpUBOValue{{}, parameters.frameCount}));
if (result.second) {
// new item inserted
const auto interpolateBuf = buildInterpUBO(paintProps, isText, zoom);
result.first->second.ubo = context.createUniformBuffer(&interpolateBuf, sizeof(interpolateBuf));
} else if (result.first->second.updatedFrame < parameters.frameCount) {
// existing item found, but hasn't been updated this frame
const auto interpolateBuf = buildInterpUBO(paintProps, isText, zoom);
result.first->second.ubo->update(&interpolateBuf, sizeof(interpolateBuf));
result.first->second.updatedFrame = parameters.frameCount;
}
return result.first->second.ubo;
};
const auto camDist = state.getCameraToCenterDistance();
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
if (!drawable.getTileID() || !drawable.getData()) {
@@ -85,6 +126,18 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto& symbolData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
const auto isText = (symbolData.symbolType == SymbolType::Text);
const auto* textBinders = isText ? static_cast<SymbolSDFTextProgram::Binders*>(drawable.getBinders()) : nullptr;
const auto* iconBinders = isText ? nullptr : static_cast<SymbolIconProgram::Binders*>(drawable.getBinders());
const auto bucket = std::static_pointer_cast<SymbolBucket>(drawable.getBucket());
const auto* tile = drawable.getRenderTile();
if (!bucket || !tile || (!textBinders && !iconBinders)) {
assert(false);
return;
}
const auto& paintProperties = bucket->paintProperties.at(id);
// from RenderTile::translatedMatrix
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();
const auto anchor = isText ? evaluated.get<style::TextTranslateAnchor>()
@@ -131,9 +184,36 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
/*.pad=*/{0},
};
const auto& sizeBinder = isText ? bucket->textSizeBinder : bucket->iconSizeBinder;
const auto size = sizeBinder->evaluateForZoom(currentZoom);
const auto tileUBO = SymbolTilePropsUBO{
/* .is_text = */ isText,
/* .is_halo = */ symbolData.isHalo,
/* .pitch_with_map = */ (symbolData.pitchAlignment == style::AlignmentType::Map),
/* .is_size_zoom_constant = */ size.isZoomConstant,
/* .is_size_feature_constant = */ size.isFeatureConstant,
/* .size_t = */ size.sizeT,
/* .size = */ size.size,
/* .padding = */ 0,
};
auto& drawableUniforms = drawable.mutableUniformBuffers();
drawableUniforms.createOrUpdate(idSymbolDrawableUBO, &drawableUBO, context);
drawableUniforms.createOrUpdate(idSymbolTilePropsUBO, &tileUBO, context);
drawableUniforms.set(idSymbolInterpolateUBO, getInterpUBO(tileID, isText, paintProperties));
});
// Regularly remove UBOs which are not being updated
constexpr int pruneFrameInterval = 10;
if ((parameters.frameCount % pruneFrameInterval) == 0) {
for (auto i = interpUBOs.begin(); i != interpUBOs.end();) {
if (i->second.updatedFrame < parameters.frameCount) {
i = interpUBOs.erase(i);
} else {
i++;
}
}
}
}
} // namespace mbgl

View File

@@ -1,6 +1,9 @@
#pragma once
#include <mbgl/renderer/layer_tweaker.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/containers.hpp>
#include <mbgl/util/hash.hpp>
#include <string>
@@ -13,14 +16,28 @@ class SymbolLayerTweaker : public LayerTweaker {
public:
SymbolLayerTweaker(std::string id_, Immutable<style::LayerProperties> properties)
: LayerTweaker(std::move(id_), properties) {}
public:
~SymbolLayerTweaker() override = default;
void execute(LayerGroupBase&, const PaintParameters&) override;
private:
gfx::UniformBufferPtr evaluatedPropsUniformBuffer;
// Interpolation UBOs are shared by drawables of the same type (text/icon) in each tile
struct InterpUBOKey {
UnwrappedTileID tileID;
bool isText;
bool operator==(const InterpUBOKey& other) const { return isText == other.isText && tileID == other.tileID; }
};
struct InterpUBOValue {
gfx::UniformBufferPtr ubo;
uint64_t updatedFrame = 0;
};
struct InterpUBOHash {
size_t operator()(const InterpUBOKey& k) const { return util::hash(k.tileID, k.isText); }
};
mbgl::unordered_map<InterpUBOKey, InterpUBOValue, InterpUBOHash> interpUBOs;
};
} // namespace mbgl

View File

@@ -717,11 +717,13 @@ struct InterpolationUniform {
static constexpr auto name() { return concat_literals<&Attr::name, &string_literal<'_', 't'>::value>::value(); }
};
class PaintPropertyBindersBase {};
template <class Ps>
class PaintPropertyBinders;
template <class... Ps>
class PaintPropertyBinders<TypeList<Ps...>> {
class PaintPropertyBinders<TypeList<Ps...>> : public PaintPropertyBindersBase {
private:
template <class T, class PossiblyEvaluatedType, class... As>
struct Detail;
@@ -774,7 +776,7 @@ public:
void setPatternParameters(const std::optional<ImagePosition>& posA,
const std::optional<ImagePosition>& posB,
const CrossfadeParameters& crossfade) const {
const CrossfadeParameters& crossfade) {
util::ignore({(binders.template get<Ps>()->setPatternParameters(posA, posB, crossfade), 0)...});
}

View File

@@ -21,7 +21,8 @@ using namespace style;
RenderLayer::RenderLayer(Immutable<style::LayerProperties> properties)
: evaluatedProperties(std::move(properties)),
baseImpl(evaluatedProperties->baseImpl) {}
baseImpl(evaluatedProperties->baseImpl),
renderTilesOwner(makeMutable<std::vector<RenderTile>>()) {}
void RenderLayer::transition(const TransitionParameters& parameters, Immutable<style::Layer::Impl> newImpl) {
baseImpl = std::move(newImpl);
@@ -58,6 +59,7 @@ void RenderLayer::prepare(const LayerPrepareParameters& params) {
assert(params.source);
assert(params.source->isEnabled());
renderTiles = params.source->getRenderTiles();
renderTilesOwner = params.source->getRawRenderTiles();
addRenderPassesFromTiles();
#if MLN_DRAWABLE_RENDERER

View File

@@ -276,6 +276,9 @@ protected:
// Stores current set of tiles to be rendered for this layer.
RenderTiles renderTiles;
// Retains ownership of tiles
Immutable<std::vector<RenderTile>> renderTilesOwner;
// Stores what render passes this layer is currently enabled for. This depends on the
// evaluated StyleProperties object and is updated accordingly.
RenderPass passes = RenderPass::None;

View File

@@ -1,16 +1,16 @@
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/annotation/render_annotation_source.hpp>
#include <mbgl/layermanager/layer_manager.hpp>
#include <mbgl/renderer/render_source_observer.hpp>
#include <mbgl/renderer/sources/render_geojson_source.hpp>
#include <mbgl/renderer/sources/render_raster_source.hpp>
#include <mbgl/renderer/sources/render_raster_dem_source.hpp>
#include <mbgl/renderer/sources/render_vector_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/annotation/render_annotation_source.hpp>
#include <mbgl/renderer/sources/render_image_source.hpp>
#include <mbgl/renderer/sources/render_custom_geometry_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/layermanager/layer_manager.hpp>
#include <mbgl/util/constants.hpp>
#include <memory>
@@ -91,4 +91,8 @@ uint8_t RenderSource::getMaxZoom() const {
return util::TERRAIN_RGB_MAXZOOM;
}
Immutable<std::vector<RenderTile>> RenderSource::getRawRenderTiles() const {
return makeMutable<std::vector<RenderTile>>();
}
} // namespace mbgl

View File

@@ -76,6 +76,7 @@ public:
// If supported, returns pointer to image data; returns nullptr otherwise.
virtual const ImageSourceRenderData* getImageRenderData() const { return nullptr; }
virtual const Tile* getRenderedTile(const UnwrappedTileID&) const { return nullptr; }
virtual Immutable<std::vector<RenderTile>> getRawRenderTiles() const;
virtual std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures(
const ScreenLineString& geometry,

View File

@@ -1,15 +1,15 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/renderer/buckets/debug_bucket.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/renderer/tile_render_data.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/math.hpp>
namespace mbgl {

View File

@@ -29,6 +29,7 @@ public:
RenderTiles getRenderTiles() const override;
RenderTiles getRenderTilesSortedByYPosition() const override;
const Tile* getRenderedTile(const UnwrappedTileID&) const override;
Immutable<std::vector<RenderTile>> getRawRenderTiles() const override { return renderTiles; }
std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures(
const ScreenLineString& geometry,