Move UBO updates from render layers to tweakers (#2703)
This commit is contained in:
@@ -18,12 +18,16 @@
|
|||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
|
class Bucket;
|
||||||
class Color;
|
class Color;
|
||||||
class PaintParameters;
|
|
||||||
class LayerTweaker;
|
class LayerTweaker;
|
||||||
|
class PaintParameters;
|
||||||
|
class PaintPropertyBindersBase;
|
||||||
enum class RenderPass : uint8_t;
|
enum class RenderPass : uint8_t;
|
||||||
|
class RenderTile;
|
||||||
|
|
||||||
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
|
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
|
||||||
|
using RenderTiles = std::shared_ptr<const std::vector<std::reference_wrapper<const RenderTile>>>;
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
@@ -245,6 +249,17 @@ public:
|
|||||||
/// Set origin point
|
/// Set origin point
|
||||||
void setOrigin(std::optional<Point<double>> p) { origin = std::move(p); }
|
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();
|
const std::chrono::duration<double> createTime = util::MonotonicTimer::now();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ class LayerProperties;
|
|||||||
enum class TranslateAnchorType : bool;
|
enum class TranslateAnchorType : bool;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
||||||
class TransformState;
|
|
||||||
class LayerGroupBase;
|
class LayerGroupBase;
|
||||||
class PaintParameters;
|
class PaintParameters;
|
||||||
class RenderTree;
|
class RenderTree;
|
||||||
|
class TransformState;
|
||||||
class UnwrappedTileID;
|
class UnwrappedTileID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
#if MLN_USE_UNORDERED_DENSE
|
#if MLN_USE_UNORDERED_DENSE
|
||||||
template <typename Key, typename Value>
|
template <typename Key, typename Value, typename Hash = std::hash<Key>>
|
||||||
using unordered_map = ankerl::unordered_dense::map<Key, Value>;
|
using unordered_map = ankerl::unordered_dense::map<Key, Value, Hash>;
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
using unordered_set = ankerl::unordered_dense::set<Value>;
|
using unordered_set = ankerl::unordered_dense::set<Value>;
|
||||||
#else
|
#else
|
||||||
template <typename Key, typename Value>
|
template <typename Key, typename Value, typename Hash = std::hash<Key>>
|
||||||
using unordered_map = std::unordered_map<Key, Value>;
|
using unordered_map = std::unordered_map<Key, Value, Hash>;
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
using unordered_set = std::unordered_set<Value>;
|
using unordered_set = std::unordered_set<Value>;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <mbgl/gfx/index_vector.hpp>
|
#include <mbgl/gfx/index_vector.hpp>
|
||||||
#include <mbgl/gfx/types.hpp>
|
#include <mbgl/gfx/types.hpp>
|
||||||
#include <mbgl/renderer/render_pass.hpp>
|
#include <mbgl/renderer/render_pass.hpp>
|
||||||
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
@@ -13,6 +14,12 @@ namespace gfx {
|
|||||||
struct Drawable::Impl {
|
struct Drawable::Impl {
|
||||||
gfx::ColorMode colorMode = gfx::ColorMode::disabled();
|
gfx::ColorMode colorMode = gfx::ColorMode::disabled();
|
||||||
gfx::CullFaceMode cullFaceMode = gfx::CullFaceMode::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_)
|
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);
|
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 gfx
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <mbgl/gfx/context.hpp>
|
#include <mbgl/gfx/context.hpp>
|
||||||
#include <mbgl/gfx/drawable.hpp>
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
|
#include <mbgl/programs/circle_program.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/render_tree.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());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#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 pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
|
||||||
const bool scaleWithMap = evaluated.get<CirclePitchScale>() == CirclePitchScaleType::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();
|
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& translation = evaluated.get<CircleTranslate>();
|
||||||
const auto anchor = evaluated.get<CircleTranslateAnchor>();
|
const auto anchor = evaluated.get<CircleTranslateAnchor>();
|
||||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||||
@@ -71,7 +78,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
|
|||||||
const auto matrix = getTileMatrix(
|
const auto matrix = getTileMatrix(
|
||||||
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
|
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}
|
const auto extrudeScale = pitchWithMap ? std::array<float, 2>{pixelsToTileUnits, pixelsToTileUnits}
|
||||||
: parameters.pixelsToGLUnits;
|
: parameters.pixelsToGLUnits;
|
||||||
|
|
||||||
@@ -82,6 +89,20 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
|
|||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idCircleDrawableUBO, &drawableUBO, context);
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
#include <mbgl/gfx/renderer_backend.hpp>
|
#include <mbgl/gfx/renderer_backend.hpp>
|
||||||
#include <mbgl/programs/fill_extrusion_program.hpp>
|
#include <mbgl/programs/fill_extrusion_program.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
#include <mbgl/renderer/render_tree.hpp>
|
#include <mbgl/renderer/render_tree.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||||
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
|
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
|
||||||
#include <mbgl/shaders/shader_program_base.hpp>
|
#include <mbgl/shaders/shader_program_base.hpp>
|
||||||
#include <mbgl/style/layers/fill_extrusion_layer_properties.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
|
#if MLN_RENDER_BACKEND_METAL
|
||||||
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
#include <mbgl/shaders/mtl/fill_extrusion.hpp>
|
||||||
@@ -62,11 +61,22 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
|
|||||||
|
|
||||||
propertiesUpdated = false;
|
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) {
|
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
||||||
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
|
if (!drawable.getTileID() || !checkTweakDrawable(drawable)) {
|
||||||
return;
|
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 UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||||
const auto& translation = evaluated.get<FillExtrusionTranslate>();
|
const auto& translation = evaluated.get<FillExtrusionTranslate>();
|
||||||
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
|
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
|
||||||
@@ -90,6 +100,13 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
|
|||||||
textureSize = tex->getSize();
|
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 = {
|
const FillExtrusionDrawableUBO drawableUBO = {
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
/* .matrix = */ util::cast<float>(matrix),
|
||||||
/* .texsize = */ {static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
/* .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,
|
/* .height_factor = */ heightFactor,
|
||||||
/* .tile_ratio = */ tileRatio};
|
/* .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();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idFillExtrusionDrawableUBO, &drawableUBO, context);
|
drawableUniforms.createOrUpdate(idFillExtrusionDrawableUBO, &drawableUBO, context);
|
||||||
|
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
|
||||||
|
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <mbgl/gfx/renderer_backend.hpp>
|
#include <mbgl/gfx/renderer_backend.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
||||||
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
#include <mbgl/renderer/render_tree.hpp>
|
#include <mbgl/renderer/render_tree.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/paint_property_binder.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& translation = evaluated.get<FillTranslate>();
|
||||||
const auto anchor = evaluated.get<FillTranslateAnchor>();
|
const auto anchor = evaluated.get<FillTranslateAnchor>();
|
||||||
|
const auto zoom = static_cast<float>(parameters.state.getZoom());
|
||||||
const auto intZoom = parameters.state.getIntegerZoom();
|
const auto intZoom = parameters.state.getIntegerZoom();
|
||||||
|
|
||||||
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
||||||
@@ -62,9 +64,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
|
|
||||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
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 inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||||
constexpr bool nearClipped = false;
|
constexpr bool nearClipped = false;
|
||||||
|
|
||||||
const auto matrix = getTileMatrix(
|
const auto matrix = getTileMatrix(
|
||||||
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
|
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
|
||||||
|
|
||||||
@@ -88,11 +101,27 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
case RenderFillLayer::FillVariant::Fill: {
|
case RenderFillLayer::FillVariant::Fill: {
|
||||||
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
const FillDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
||||||
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case RenderFillLayer::FillVariant::FillOutline: {
|
case RenderFillLayer::FillVariant::FillOutline: {
|
||||||
const FillOutlineDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
const FillOutlineDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix)};
|
||||||
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case RenderFillLayer::FillVariant::FillPattern: {
|
case RenderFillLayer::FillVariant::FillPattern: {
|
||||||
@@ -105,6 +134,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case RenderFillLayer::FillVariant::FillOutlinePattern: {
|
case RenderFillLayer::FillVariant::FillOutlinePattern: {
|
||||||
@@ -116,6 +159,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
/*.tile_ratio = */ tileRatio,
|
/*.tile_ratio = */ tileRatio,
|
||||||
0};
|
0};
|
||||||
drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, context);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case RenderFillLayer::FillVariant::FillOutlineTriangulated: {
|
case RenderFillLayer::FillVariant::FillOutlineTriangulated: {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <mbgl/gfx/context.hpp>
|
#include <mbgl/gfx/context.hpp>
|
||||||
#include <mbgl/gfx/drawable.hpp>
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
|
#include <mbgl/programs/heatmap_program.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/render_static_data.hpp>
|
#include <mbgl/renderer/render_static_data.hpp>
|
||||||
@@ -21,7 +22,7 @@ using namespace shaders;
|
|||||||
|
|
||||||
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
|
void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
|
||||||
auto& context = parameters.context;
|
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;
|
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
if (layerGroup.empty()) {
|
if (layerGroup.empty()) {
|
||||||
@@ -52,17 +53,29 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamet
|
|||||||
|
|
||||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
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 nearClipped = false;
|
||||||
constexpr bool inViewportPixelUnits = false;
|
constexpr bool inViewportPixelUnits = false;
|
||||||
const auto matrix = getTileMatrix(
|
const auto matrix = getTileMatrix(
|
||||||
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, nearClipped, inViewportPixelUnits, drawable);
|
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, nearClipped, inViewportPixelUnits, drawable);
|
||||||
const HeatmapDrawableUBO drawableUBO = {
|
const HeatmapDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),
|
||||||
/* .matrix = */ util::cast<float>(matrix),
|
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, zoom),
|
||||||
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
|
/* .padding = */ {0}};
|
||||||
/* .padding = */ {0}};
|
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idHeatmapDrawableUBO, &drawableUBO, context);
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
#include <mbgl/gfx/drawable.hpp>
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
#include <mbgl/gfx/line_drawable_data.hpp>
|
#include <mbgl/gfx/line_drawable_data.hpp>
|
||||||
#include <mbgl/geometry/line_atlas.hpp>
|
#include <mbgl/geometry/line_atlas.hpp>
|
||||||
|
#include <mbgl/programs/line_program.hpp>
|
||||||
#include <mbgl/renderer/image_atlas.hpp>
|
#include <mbgl/renderer/image_atlas.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
#include <mbgl/shaders/line_layer_ubo.hpp>
|
#include <mbgl/shaders/line_layer_ubo.hpp>
|
||||||
#include <mbgl/shaders/shader_program_base.hpp>
|
#include <mbgl/shaders/shader_program_base.hpp>
|
||||||
#include <mbgl/style/layers/line_layer_properties.hpp>
|
#include <mbgl/style/layers/line_layer_properties.hpp>
|
||||||
#include <mbgl/util/convert.hpp>
|
|
||||||
#include <mbgl/util/logging.hpp>
|
#include <mbgl/util/logging.hpp>
|
||||||
#include <mbgl/util/math.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& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
const auto& crossfade = static_cast<const LineLayerProperties&>(*evaluatedProperties).crossfade;
|
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 zoom = static_cast<float>(parameters.state.getZoom());
|
||||||
const auto intZoom = parameters.state.getIntegerZoom();
|
const auto intZoom = parameters.state.getIntegerZoom();
|
||||||
|
|
||||||
@@ -160,17 +163,27 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
}
|
}
|
||||||
|
|
||||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
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& translation = evaluated.get<LineTranslate>();
|
||||||
const auto anchor = evaluated.get<LineTranslateAnchor>();
|
const auto anchor = evaluated.get<LineTranslateAnchor>();
|
||||||
constexpr bool nearClipped = false;
|
constexpr bool nearClipped = false;
|
||||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
|
||||||
|
|
||||||
const auto matrix = getTileMatrix(
|
const auto matrix = getTileMatrix(
|
||||||
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
|
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);
|
||||||
|
|
||||||
const LineType type = static_cast<LineType>(drawable.getType());
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
switch (type) {
|
switch (static_cast<LineType>(drawable.getType())) {
|
||||||
case LineType::Simple: {
|
case LineType::Simple: {
|
||||||
const LineDrawableUBO drawableUBO = {
|
const LineDrawableUBO drawableUBO = {
|
||||||
/*matrix = */ util::cast<float>(matrix),
|
/*matrix = */ util::cast<float>(matrix),
|
||||||
@@ -179,6 +192,17 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
0,
|
0,
|
||||||
0};
|
0};
|
||||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
|
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;
|
} break;
|
||||||
|
|
||||||
case LineType::Gradient: {
|
case LineType::Gradient: {
|
||||||
@@ -189,6 +213,17 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
0,
|
0,
|
||||||
0};
|
0};
|
||||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
|
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;
|
} break;
|
||||||
|
|
||||||
case LineType::Pattern: {
|
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)),
|
/*ratio =*/1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
|
||||||
/*fade =*/crossfade.t};
|
/*fade =*/crossfade.t};
|
||||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
|
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;
|
} break;
|
||||||
|
|
||||||
case LineType::SDF: {
|
case LineType::SDF: {
|
||||||
@@ -246,13 +297,24 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
|
|||||||
0,
|
0,
|
||||||
0};
|
0};
|
||||||
drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, context);
|
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;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
using namespace std::string_literals;
|
|
||||||
Log::Error(Event::General,
|
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;
|
} break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ void RenderCircleLayer::render(PaintParameters& parameters) {
|
|||||||
const auto& evaluated = getEvaluated<CircleLayerProperties>(data->layerProperties);
|
const auto& evaluated = getEvaluated<CircleLayerProperties>(data->layerProperties);
|
||||||
const bool scaleWithMap = evaluated.template get<CirclePitchScale>() == CirclePitchScaleType::Map;
|
const bool scaleWithMap = evaluated.template get<CirclePitchScale>() == CirclePitchScaleType::Map;
|
||||||
const bool pitchWithMap = evaluated.template get<CirclePitchAlignment>() == AlignmentType::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;
|
using LayoutUniformValues = CircleProgram::LayoutUniformValues;
|
||||||
const auto& allUniformValues = CircleProgram::computeAllUniformValues(
|
const auto& allUniformValues = CircleProgram::computeAllUniformValues(
|
||||||
@@ -274,9 +274,9 @@ using namespace shaders;
|
|||||||
|
|
||||||
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState&,
|
||||||
[[maybe_unused]] const std::shared_ptr<UpdateParameters>&,
|
const std::shared_ptr<UpdateParameters>&,
|
||||||
[[maybe_unused]] const RenderTree& renderTree,
|
const RenderTree&,
|
||||||
UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
if (!renderTiles || renderTiles->empty()) {
|
if (!renderTiles || renderTiles->empty()) {
|
||||||
removeAllDrawables();
|
removeAllDrawables();
|
||||||
@@ -327,9 +327,9 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
continue;
|
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 vertexCount = bucket.vertices.elements();
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
|
|
||||||
const auto prevBucketID = getRenderTileBucketID(tileID);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
||||||
@@ -338,37 +338,18 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
setRenderTileBucketID(tileID, bucket.getID());
|
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.
|
// If there are already drawables for this tile, update their UBOs and move on to the next tile.
|
||||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||||
if (drawable.getLayerTweaker() != layerTweaker) {
|
if (drawable.getLayerTweaker() != layerTweaker) {
|
||||||
// This drawable was produced on a previous style/bucket, and should not be updated.
|
// This drawable was produced on a previous style/bucket, and should not be updated.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
|
||||||
drawableUniforms.createOrUpdate(idCircleInterpolateUBO, &interpolateUBO, context);
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
|
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
|
|
||||||
|
|
||||||
propertiesAsUniforms.first.clear();
|
propertiesAsUniforms.first.clear();
|
||||||
propertiesAsUniforms.second.clear();
|
propertiesAsUniforms.second.clear();
|
||||||
|
|
||||||
@@ -413,9 +394,8 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
for (auto& drawable : circleBuilder->clearDrawables()) {
|
for (auto& drawable : circleBuilder->clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
drawable->setTileID(tileID);
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
drawable->setLayerTweaker(layerTweaker);
|
||||||
|
drawable->setBinders(renderData->bucket, &paintPropertyBinders);
|
||||||
auto& drawableUniforms = drawable->mutableUniformBuffers();
|
drawable->setRenderTile(renderTilesOwner, &tile);
|
||||||
drawableUniforms.set(idCircleInterpolateUBO, interpBuffer);
|
|
||||||
|
|
||||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||||
++stats.drawablesAdded;
|
++stats.drawablesAdded;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
||||||
#include <mbgl/tile/geometry_tile.hpp>
|
#include <mbgl/tile/geometry_tile.hpp>
|
||||||
#include <mbgl/tile/tile.hpp>
|
#include <mbgl/tile/tile.hpp>
|
||||||
#include <mbgl/util/convert.hpp>
|
|
||||||
#include <mbgl/util/intersection_tests.hpp>
|
#include <mbgl/util/intersection_tests.hpp>
|
||||||
#include <mbgl/util/math.hpp>
|
#include <mbgl/util/math.hpp>
|
||||||
|
|
||||||
@@ -112,13 +111,13 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
|||||||
const auto& crossfade_,
|
const auto& crossfade_,
|
||||||
const gfx::StencilMode& stencilMode,
|
const gfx::StencilMode& stencilMode,
|
||||||
const gfx::ColorMode& colorMode,
|
const gfx::ColorMode& colorMode,
|
||||||
const auto& tileBucket,
|
auto& tileBucket,
|
||||||
const auto& uniformValues,
|
const auto& uniformValues,
|
||||||
const std::optional<ImagePosition>& patternPositionA,
|
const std::optional<ImagePosition>& patternPositionA,
|
||||||
const std::optional<ImagePosition>& patternPositionB,
|
const std::optional<ImagePosition>& patternPositionB,
|
||||||
const auto& textureBindings,
|
const auto& textureBindings,
|
||||||
const std::string& uniqueName) {
|
const std::string& uniqueName) {
|
||||||
const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
|
||||||
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
|
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
|
||||||
|
|
||||||
const auto allUniformValues = programInstance.computeAllUniformValues(
|
const auto allUniformValues = programInstance.computeAllUniformValues(
|
||||||
@@ -152,7 +151,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
|||||||
if (!renderData) {
|
if (!renderData) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||||
draw(*fillExtrusionProgram,
|
draw(*fillExtrusionProgram,
|
||||||
evaluated,
|
evaluated,
|
||||||
crossfade,
|
crossfade,
|
||||||
@@ -200,7 +199,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
|||||||
if (!renderData) {
|
if (!renderData) {
|
||||||
continue;
|
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> patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||||
const std::optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
const std::optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||||
const auto numTiles = std::pow(2, tile.id.canonical.z);
|
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,
|
void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState&,
|
||||||
const std::shared_ptr<UpdateParameters>&,
|
const std::shared_ptr<UpdateParameters>&,
|
||||||
const RenderTree& /*renderTree*/,
|
const RenderTree&,
|
||||||
UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
|
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
|
||||||
removeAllDrawables();
|
removeAllDrawables();
|
||||||
@@ -304,7 +303,6 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
|
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
|
||||||
|
|
||||||
const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
|
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()`
|
// `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
|
// 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;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto zoom = static_cast<float>(state.getZoom());
|
|
||||||
const auto layerPrefix = getID() + "/";
|
const auto layerPrefix = getID() + "/";
|
||||||
const auto hasPattern = !unevaluated.get<FillExtrusionPattern>().isUndefined();
|
const auto hasPattern = !unevaluated.get<FillExtrusionPattern>().isUndefined();
|
||||||
const auto opaque = evaluated.get<FillExtrusionOpacity>() >= 1;
|
const auto opaque = evaluated.get<FillExtrusionOpacity>() >= 1;
|
||||||
@@ -347,7 +344,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& renderData = *optRenderData;
|
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);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
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 vertexCount = bucket.vertices.elements();
|
||||||
const auto defPattern = mbgl::Faded<expression::Image>{"", ""};
|
auto& binders = bucket.paintPropertyBinders.at(getID());
|
||||||
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},
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we already have drawables for this tile, update them.
|
// If we already have drawables for this tile, update them.
|
||||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
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.
|
// This drawable was produced on a previous style/bucket, and should not be updated.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
|
||||||
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
|
|
||||||
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
if (updateTile(drawPass, tileID, std::move(updateExisting))) {
|
if (updateTile(drawPass, tileID, std::move(updateExisting))) {
|
||||||
@@ -512,11 +482,10 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
|
|
||||||
for (auto& drawable : builder.clearDrawables()) {
|
for (auto& drawable : builder.clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
drawable->setTileID(tileID);
|
||||||
|
drawable->setType(static_cast<std::size_t>(hasPattern));
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
drawable->setLayerTweaker(layerTweaker);
|
||||||
|
drawable->setBinders(renderData.bucket, &binders);
|
||||||
auto& drawableUniforms = drawable->mutableUniformBuffers();
|
drawable->setRenderTile(renderTilesOwner, &tile);
|
||||||
drawableUniforms.createOrUpdate(idFillExtrusionTilePropsUBO, &tilePropsUBO, context);
|
|
||||||
drawableUniforms.createOrUpdate(idFillExtrusionInterpolateUBO, &interpUBO, context);
|
|
||||||
|
|
||||||
tileLayerGroup->addDrawable(drawPass, tileID, std::move(drawable));
|
tileLayerGroup->addDrawable(drawPass, tileID, std::move(drawable));
|
||||||
++stats.drawablesAdded;
|
++stats.drawablesAdded;
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
|
|||||||
const auto& indexBuffer,
|
const auto& indexBuffer,
|
||||||
const auto& segments,
|
const auto& segments,
|
||||||
auto&& textureBindings) {
|
auto&& textureBindings) {
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
|
|
||||||
const auto allUniformValues = programInstance.computeAllUniformValues(
|
const auto allUniformValues = programInstance.computeAllUniformValues(
|
||||||
FillProgram::LayoutUniformValues{
|
FillProgram::LayoutUniformValues{
|
||||||
@@ -214,7 +214,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
|
|||||||
const auto& indexBuffer,
|
const auto& indexBuffer,
|
||||||
const auto& segments,
|
const auto& segments,
|
||||||
auto&& textureBindings) {
|
auto&& textureBindings) {
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
|
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
|
||||||
|
|
||||||
const auto allUniformValues = programInstance.computeAllUniformValues(
|
const auto allUniformValues = programInstance.computeAllUniformValues(
|
||||||
@@ -297,10 +297,10 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
|
|||||||
|
|
||||||
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState&,
|
||||||
const std::shared_ptr<UpdateParameters>&,
|
const std::shared_ptr<UpdateParameters>&,
|
||||||
[[maybe_unused]] const RenderTree& renderTree,
|
const RenderTree&,
|
||||||
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
if (!renderTiles || renderTiles->empty()) {
|
if (!renderTiles || renderTiles->empty()) {
|
||||||
removeAllDrawables();
|
removeAllDrawables();
|
||||||
return;
|
return;
|
||||||
@@ -376,7 +376,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
|
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);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
||||||
@@ -386,95 +386,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
setRenderTileBucketID(tileID, bucket.getID());
|
setRenderTileBucketID(tileID, bucket.getID());
|
||||||
|
|
||||||
const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
|
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;
|
gfx::DrawableTweakerPtr atlasTweaker;
|
||||||
auto getAtlasTweaker = [&]() {
|
auto getAtlasTweaker = [&]() {
|
||||||
@@ -498,6 +409,8 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
propertiesAsUniforms.second.clear();
|
propertiesAsUniforms.second.clear();
|
||||||
|
|
||||||
// `Fill*Program` all use `style::FillPaintProperties`
|
// `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();
|
auto vertexAttrs = context.createVertexAttributeArray();
|
||||||
vertexAttrs->readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
|
vertexAttrs->readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
|
||||||
binders, evaluated, propertiesAsUniforms, idFillColorVertexAttribute);
|
binders, evaluated, propertiesAsUniforms, idFillColorVertexAttribute);
|
||||||
@@ -513,38 +426,10 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
|
|
||||||
// If we already have drawables for this tile, update them.
|
// If we already have drawables for this tile, update them.
|
||||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
if (drawable.getLayerTweaker() != layerTweaker) {
|
||||||
switch (static_cast<FillVariant>(drawable.getType())) {
|
// This drawable was produced on a previous style/bucket, and should not be updated.
|
||||||
case FillVariant::Fill: {
|
return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawable.setVertexAttributes(vertexAttrs);
|
drawable.setVertexAttributes(vertexAttrs);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -552,6 +437,16 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
continue;
|
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 always occurs in translucent pass, defaults to fill color
|
||||||
// Outline does not default to fill in the pattern case
|
// Outline does not default to fill in the pattern case
|
||||||
const auto doOutline = evaluated.get<FillAntialias>() && (unevaluated.get<FillPattern>().isUndefined() ||
|
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.data(),
|
||||||
bucket.lineSegments.size());
|
bucket.lineSegments.size());
|
||||||
|
|
||||||
// finish
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
addDrawable(std::move(drawable), FillVariant::FillOutlineTriangulated);
|
||||||
drawable->setType(static_cast<size_t>(FillVariant::FillOutlineTriangulated));
|
|
||||||
fillTileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
|
||||||
++stats.drawablesAdded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -648,21 +539,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto finish = [&](gfx::DrawableBuilder& builder,
|
const auto finish = [&](gfx::DrawableBuilder& builder, FillVariant type) {
|
||||||
const size_t interpolateUBOId,
|
|
||||||
const auto& interpolateUBO,
|
|
||||||
FillVariant type) {
|
|
||||||
builder.flush(context);
|
builder.flush(context);
|
||||||
|
|
||||||
for (auto& drawable : builder.clearDrawables()) {
|
for (auto& drawable : builder.clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
addDrawable(std::move(drawable), type);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -688,7 +569,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
bucket.sharedTriangles,
|
bucket.sharedTriangles,
|
||||||
bucket.triangleSegments.data(),
|
bucket.triangleSegments.data(),
|
||||||
bucket.triangleSegments.size());
|
bucket.triangleSegments.size());
|
||||||
finish(*fillBuilder, idFillInterpolateUBO, getFillInterpolateUBO(), FillVariant::Fill);
|
finish(*fillBuilder, FillVariant::Fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MLN_TRIANGULATE_FILL_OUTLINES
|
#if MLN_TRIANGULATE_FILL_OUTLINES
|
||||||
@@ -704,8 +585,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
bucket.sharedBasicLineIndexes,
|
bucket.sharedBasicLineIndexes,
|
||||||
bucket.basicLineSegments.data(),
|
bucket.basicLineSegments.data(),
|
||||||
bucket.basicLineSegments.size());
|
bucket.basicLineSegments.size());
|
||||||
finish(
|
finish(*outlineBuilder, FillVariant::FillOutline);
|
||||||
*outlineBuilder, idFillInterpolateUBO, getFillInterpolateUBO(), FillVariant::FillOutline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,7 +597,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
bucket.sharedBasicLineIndexes,
|
bucket.sharedBasicLineIndexes,
|
||||||
bucket.basicLineSegments.data(),
|
bucket.basicLineSegments.data(),
|
||||||
bucket.basicLineSegments.size());
|
bucket.basicLineSegments.size());
|
||||||
finish(*outlineBuilder, idFillInterpolateUBO, getFillOutlineInterpolateUBO(), FillVariant::FillOutline);
|
finish(*outlineBuilder, FillVariant::FillOutline);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@@ -770,24 +650,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
outlinePatternBuilder->addTweaker(getAtlasTweaker());
|
outlinePatternBuilder->addTweaker(getAtlasTweaker());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto finish = [&](gfx::DrawableBuilder& builder,
|
const auto finish = [&](gfx::DrawableBuilder& builder, FillVariant type) {
|
||||||
const size_t interpolateNameId,
|
|
||||||
const auto& interpolateUBO,
|
|
||||||
const size_t tileUBOId,
|
|
||||||
const auto& tileUBO,
|
|
||||||
FillVariant type) {
|
|
||||||
builder.flush(context);
|
builder.flush(context);
|
||||||
|
|
||||||
for (auto& drawable : builder.clearDrawables()) {
|
for (auto& drawable : builder.clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
addDrawable(std::move(drawable), type);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -806,12 +673,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
bucket.triangleSegments.data(),
|
bucket.triangleSegments.data(),
|
||||||
bucket.triangleSegments.size());
|
bucket.triangleSegments.size());
|
||||||
|
|
||||||
finish(*patternBuilder,
|
finish(*patternBuilder, FillVariant::FillPattern);
|
||||||
idFillInterpolateUBO,
|
|
||||||
getFillPatternInterpolateUBO(),
|
|
||||||
idFillTilePropsUBO,
|
|
||||||
getFillPatternTilePropsUBO(),
|
|
||||||
FillVariant::FillPattern);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doOutline && outlinePatternBuilder && bucket.sharedBasicLineIndexes->elements()) {
|
if (doOutline && outlinePatternBuilder && bucket.sharedBasicLineIndexes->elements()) {
|
||||||
@@ -823,12 +685,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
bucket.basicLineSegments.data(),
|
bucket.basicLineSegments.data(),
|
||||||
bucket.basicLineSegments.size());
|
bucket.basicLineSegments.size());
|
||||||
|
|
||||||
finish(*outlinePatternBuilder,
|
finish(*outlinePatternBuilder, FillVariant::FillOutlinePattern);
|
||||||
idFillInterpolateUBO,
|
|
||||||
getFillOutlinePatternInterpolateUBO(),
|
|
||||||
idFillTilePropsUBO,
|
|
||||||
getFillOutlinePatternTilePropsUBO(),
|
|
||||||
FillVariant::FillOutlinePattern);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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(
|
const auto allUniformValues = HeatmapProgram::computeAllUniformValues(
|
||||||
HeatmapProgram::LayoutUniformValues{
|
HeatmapProgram::LayoutUniformValues{
|
||||||
@@ -361,9 +361,9 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
|
auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
|
||||||
const auto vertexCount = bucket.vertices.elements();
|
const auto vertexCount = bucket.vertices.elements();
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
|
|
||||||
const auto prevBucketID = getRenderTileBucketID(tileID);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
||||||
@@ -372,37 +372,14 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
setRenderTileBucketID(tileID, bucket.getID());
|
setRenderTileBucketID(tileID, bucket.getID());
|
||||||
|
|
||||||
const float zoom = static_cast<float>(state.getZoom());
|
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||||
|
|
||||||
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) {
|
|
||||||
if (drawable.getLayerTweaker() != layerTweaker) {
|
if (drawable.getLayerTweaker() != layerTweaker) {
|
||||||
// This drawable was produced on a previous style/bucket, and should not be updated.
|
// This drawable was produced on a previous style/bucket, and should not be updated.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
// We assume vertex attributes don't change, and so don't update them to avoid re-uploading
|
};
|
||||||
// drawable.setVertexAttributes(heatmapVertexAttrs);
|
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
|
||||||
|
|
||||||
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
|
||||||
|
|
||||||
if (auto buffer = getInterpolateBuffer()) {
|
|
||||||
drawableUniforms.set(idHeatmapInterpolateUBO, std::move(buffer));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updatedCount > 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,13 +437,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
for (auto& drawable : heatmapBuilder->clearDrawables()) {
|
for (auto& drawable : heatmapBuilder->clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
drawable->setTileID(tileID);
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
drawable->setLayerTweaker(layerTweaker);
|
||||||
|
drawable->setBinders(renderData->bucket, &paintPropertyBinders);
|
||||||
auto& drawableUniforms = drawable->mutableUniformBuffers();
|
drawable->setRenderTile(renderTilesOwner, &tile);
|
||||||
|
|
||||||
if (auto buffer = getInterpolateBuffer()) {
|
|
||||||
drawableUniforms.set(idHeatmapInterpolateUBO, std::move(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||||
++stats.drawablesAdded;
|
++stats.drawablesAdded;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ void RenderLineLayer::render(PaintParameters& parameters) {
|
|||||||
const std::optional<ImagePosition>& patternPositionA,
|
const std::optional<ImagePosition>& patternPositionA,
|
||||||
const std::optional<ImagePosition>& patternPositionB,
|
const std::optional<ImagePosition>& patternPositionB,
|
||||||
auto&& textureBindings) {
|
auto&& textureBindings) {
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
|
|
||||||
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade);
|
paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade);
|
||||||
|
|
||||||
@@ -355,12 +355,20 @@ float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if MLN_DRAWABLE_RENDERER
|
#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,
|
void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState&,
|
||||||
[[maybe_unused]] const std::shared_ptr<UpdateParameters>& parameters,
|
[[maybe_unused]] const std::shared_ptr<UpdateParameters>& parameters,
|
||||||
[[maybe_unused]] const RenderTree& renderTree,
|
const RenderTree&,
|
||||||
[[maybe_unused]] UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
if (!renderTiles || renderTiles->empty()) {
|
if (!renderTiles || renderTiles->empty()) {
|
||||||
removeAllDrawables();
|
removeAllDrawables();
|
||||||
return;
|
return;
|
||||||
@@ -437,10 +445,6 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
builder.setVertexAttributes(std::move(vertexAttrs));
|
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);
|
tileLayerGroup->setStencilTiles(renderTiles);
|
||||||
|
|
||||||
StringIDSetsPair propertiesAsUniforms;
|
StringIDSetsPair propertiesAsUniforms;
|
||||||
@@ -459,9 +463,8 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
|
const auto& evaluated = getEvaluated<LineLayerProperties>(renderData->layerProperties);
|
||||||
const auto& crossfade = getCrossfade<LineLayerProperties>(renderData->layerProperties);
|
|
||||||
|
|
||||||
const auto prevBucketID = getRenderTileBucketID(tileID);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
||||||
@@ -470,137 +473,32 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
setRenderTileBucketID(tileID, bucket.getID());
|
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) {
|
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||||
if (drawable.getLayerTweaker() != layerTweaker) {
|
if (drawable.getLayerTweaker() != layerTweaker) {
|
||||||
// This drawable was produced on a previous style/bucket, and should not be updated.
|
// This drawable was produced on a previous style/bucket, and should not be updated.
|
||||||
return false;
|
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;
|
return true;
|
||||||
};
|
};
|
||||||
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
|
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
|
||||||
continue;
|
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.first.clear();
|
||||||
propertiesAsUniforms.second.clear();
|
propertiesAsUniforms.second.clear();
|
||||||
|
|
||||||
@@ -635,20 +533,9 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
addAttributes(*builder, bucket, std::move(vertexAttrs));
|
addAttributes(*builder, bucket, std::move(vertexAttrs));
|
||||||
setSegments(builder, bucket);
|
setSegments(builder, bucket);
|
||||||
|
|
||||||
// finish
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round
|
|
||||||
: LinePatternCap::Square;
|
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::SDF));
|
addDrawable(std::move(drawable), 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;
|
|
||||||
}
|
}
|
||||||
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
|
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
|
||||||
// pattern line
|
// pattern line
|
||||||
@@ -689,16 +576,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
|
addDrawable(std::move(drawable), 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) {
|
} else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) {
|
||||||
@@ -733,20 +611,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
if (colorRampTexture2D) {
|
if (colorRampTexture2D) {
|
||||||
builder->setTexture(colorRampTexture2D, idLineImageTexture);
|
builder->setTexture(colorRampTexture2D, idLineImageTexture);
|
||||||
|
|
||||||
// segments
|
|
||||||
setSegments(builder, bucket);
|
setSegments(builder, bucket);
|
||||||
|
|
||||||
// finish
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
|
addDrawable(std::move(drawable), LineLayerTweaker::LineType::Gradient);
|
||||||
drawable->setTileID(tileID);
|
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
|
||||||
drawable->mutableUniformBuffers().createOrUpdate(
|
|
||||||
idLineInterpolationUBO, &getLineGradientInterpolationUBO(), context);
|
|
||||||
|
|
||||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
|
||||||
++stats.drawablesAdded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -769,17 +638,9 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
addAttributes(*builder, bucket, std::move(vertexAttrs));
|
addAttributes(*builder, bucket, std::move(vertexAttrs));
|
||||||
setSegments(builder, bucket);
|
setSegments(builder, bucket);
|
||||||
|
|
||||||
// finish
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
|
addDrawable(std::move(drawable), LineLayerTweaker::LineType::Simple);
|
||||||
drawable->setTileID(tileID);
|
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
|
||||||
drawable->mutableUniformBuffers().createOrUpdate(
|
|
||||||
idLineInterpolationUBO, &getLineInterpolationUBO(), context);
|
|
||||||
|
|
||||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
|
||||||
++stats.drawablesAdded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -725,49 +725,8 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
|
|||||||
#if MLN_DRAWABLE_RENDERER
|
#if MLN_DRAWABLE_RENDERER
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const SegmentVector<SymbolTextAttributes> emptySegmentVector;
|
const SegmentVector<SymbolTextAttributes> emptySegmentVector;
|
||||||
|
constexpr auto posOffsetAttribName = "a_pos_offset";
|
||||||
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";
|
|
||||||
|
|
||||||
void updateTileAttributes(const SymbolBucket::Buffer& buffer,
|
void updateTileAttributes(const SymbolBucket::Buffer& buffer,
|
||||||
const bool isText,
|
const bool isText,
|
||||||
@@ -824,13 +783,9 @@ void updateTileAttributes(const SymbolBucket::Buffer& buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateTileDrawable(gfx::Drawable& drawable,
|
void updateTileDrawable(gfx::Drawable& drawable,
|
||||||
gfx::Context& context,
|
|
||||||
const SymbolBucket& bucket,
|
const SymbolBucket& bucket,
|
||||||
const SymbolBucket::PaintProperties& paintProps,
|
const SymbolBucket::PaintProperties& paintProps,
|
||||||
const SymbolPaintProperties::PossiblyEvaluated& evaluated,
|
const SymbolPaintProperties::PossiblyEvaluated& evaluated) {
|
||||||
const TransformState& state,
|
|
||||||
gfx::UniformBufferPtr& textInterpUBO,
|
|
||||||
gfx::UniformBufferPtr& iconInterpUBO) {
|
|
||||||
if (!drawable.getData()) {
|
if (!drawable.getData()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -838,31 +793,10 @@ void updateTileDrawable(gfx::Drawable& drawable,
|
|||||||
auto& drawData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
|
auto& drawData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
|
||||||
const auto isText = (drawData.symbolType == SymbolType::Text);
|
const auto isText = (drawData.symbolType == SymbolType::Text);
|
||||||
const auto sdfIcons = (drawData.symbolType == SymbolType::IconSDF);
|
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.
|
// This property can be set after the initial appearance of the tile, as part of the layout process.
|
||||||
drawData.bucketVariablePlacement = bucket.hasVariablePlacement;
|
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& buffer = isText ? bucket.text : (sdfIcons ? bucket.sdfIcon : bucket.icon);
|
||||||
const auto vertexCount = buffer.vertices().elements();
|
const auto vertexCount = buffer.vertices().elements();
|
||||||
|
|
||||||
@@ -973,7 +907,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState& state,
|
||||||
const std::shared_ptr<UpdateParameters>&,
|
const std::shared_ptr<UpdateParameters>&,
|
||||||
const RenderTree& /*renderTree*/,
|
const RenderTree&,
|
||||||
UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
|
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
|
||||||
removeAllDrawables();
|
removeAllDrawables();
|
||||||
@@ -1071,6 +1005,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
|
|
||||||
const auto& renderData = *optRenderData;
|
const auto& renderData = *optRenderData;
|
||||||
const auto& bucket = static_cast<const SymbolBucket&>(*renderData.bucket);
|
const auto& bucket = static_cast<const SymbolBucket&>(*renderData.bucket);
|
||||||
|
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
|
||||||
|
|
||||||
const auto prevBucketID = getRenderTileBucketID(tileID);
|
const auto prevBucketID = getRenderTileBucketID(tileID);
|
||||||
if (prevBucketID != util::SimpleIdentity::Empty && prevBucketID != bucket.getID()) {
|
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& layout = *bucket.layout;
|
||||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
|
|
||||||
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout);
|
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout);
|
||||||
const std::string suffix = isText ? "text/" : "icon/";
|
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);
|
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.
|
// If we already have drawables for this tile, update them.
|
||||||
// Just update the drawables we already created
|
// Just update the drawables we already created
|
||||||
gfx::UniformBufferPtr textInterpUBO, iconInterpUBO;
|
|
||||||
auto updateExisting = [&](gfx::Drawable& drawable) {
|
auto updateExisting = [&](gfx::Drawable& drawable) {
|
||||||
if (drawable.getLayerTweaker() != layerTweaker) {
|
if (drawable.getLayerTweaker() != layerTweaker) {
|
||||||
// This drawable was produced on a previous style/bucket, and should not be updated.
|
// 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.first.clear();
|
||||||
propertiesAsUniforms.second.clear();
|
propertiesAsUniforms.second.clear();
|
||||||
|
|
||||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderData.layerProperties);
|
updateTileDrawable(drawable, bucket, bucketPaintProperties, evaluated);
|
||||||
updateTileDrawable(
|
|
||||||
drawable, context, bucket, bucketPaintProperties, evaluated, state, textInterpUBO, iconInterpUBO);
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
if (updateTile(passes, tileID, std::move(updateExisting))) {
|
if (updateTile(passes, tileID, std::move(updateExisting))) {
|
||||||
@@ -1216,10 +1147,9 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
struct TileInfo {
|
struct TileInfo {
|
||||||
RawVertexVec textVertices, iconVertices;
|
RawVertexVec textVertices, iconVertices;
|
||||||
gfx::DrawableTweakerPtr textTweaker, iconTweaker;
|
gfx::DrawableTweakerPtr textTweaker, iconTweaker;
|
||||||
gfx::UniformBufferPtr textInterp, iconInterp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<UnwrappedTileID, TileInfo> tileCache;
|
mbgl::unordered_map<UnwrappedTileID, TileInfo> tileCache;
|
||||||
tileCache.reserve(renderTiles->size());
|
tileCache.reserve(renderTiles->size());
|
||||||
|
|
||||||
for (auto& group : renderableSegments) {
|
for (auto& group : renderableSegments) {
|
||||||
@@ -1231,7 +1161,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
|
|
||||||
const auto& tile = renderable.tile;
|
const auto& tile = renderable.tile;
|
||||||
const auto tileID = tile.id.overscaleTo(renderable.overscaledZ);
|
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);
|
const auto& buffer = isText ? bucket.text : (sdfIcons ? bucket.sdfIcon : bucket.icon);
|
||||||
|
|
||||||
if (!buffer.sharedTriangles->elements()) {
|
if (!buffer.sharedTriangles->elements()) {
|
||||||
@@ -1239,7 +1169,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& evaluated = getEvaluated<SymbolLayerProperties>(renderable.renderData.layerProperties);
|
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& layout = *bucket.layout;
|
||||||
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, 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);
|
evaluated.get<style::IconHaloWidth>().constantOr(1);
|
||||||
const auto iconFill = evaluated.get<style::IconColor>().constantOr(Color::black()).a > 0.0f;
|
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) {
|
if (builder) {
|
||||||
builder->clearTweakers();
|
builder->clearTweakers();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto draw =
|
const auto draw = [&](const gfx::ShaderGroupPtr& shaderGroup,
|
||||||
[&](const gfx::ShaderGroupPtr& shaderGroup, const bool isHalo, const std::string_view suffix) {
|
const bool isHalo,
|
||||||
if (!shaderGroup) {
|
const std::string_view suffix) {
|
||||||
return;
|
if (!shaderGroup) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We can use the same tweakers for all the segments in a tile
|
// We can use the same tweakers for all the segments in a tile
|
||||||
if (isText && !tileInfo.textTweaker) {
|
if (isText && !tileInfo.textTweaker) {
|
||||||
const bool textSizeIsZoomConstant =
|
const bool textSizeIsZoomConstant = bucket.textSizeBinder->evaluateForZoom(currentZoom).isZoomConstant;
|
||||||
bucket.textSizeBinder->evaluateForZoom(static_cast<float>(state.getZoom())).isZoomConstant;
|
tileInfo.textTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
||||||
tileInfo.textTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
idSymbolImageIconTexture,
|
||||||
idSymbolImageIconTexture,
|
idSymbolImageTexture,
|
||||||
idSymbolImageTexture,
|
isText,
|
||||||
isText,
|
false,
|
||||||
false,
|
values.rotationAlignment,
|
||||||
values.rotationAlignment,
|
false,
|
||||||
false,
|
textSizeIsZoomConstant);
|
||||||
textSizeIsZoomConstant);
|
}
|
||||||
}
|
if (!isText && !tileInfo.iconTweaker) {
|
||||||
if (!isText && !tileInfo.iconTweaker) {
|
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
|
||||||
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
|
tileInfo.iconTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
||||||
tileInfo.iconTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
idSymbolImageIconTexture,
|
||||||
idSymbolImageIconTexture,
|
idSymbolImageTexture,
|
||||||
idSymbolImageTexture,
|
isText,
|
||||||
isText,
|
sdfIcons,
|
||||||
sdfIcons,
|
values.rotationAlignment,
|
||||||
values.rotationAlignment,
|
iconScaled,
|
||||||
iconScaled,
|
false);
|
||||||
false);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!builder) {
|
if (!builder) {
|
||||||
builder = context.createDrawableBuilder(layerPrefix);
|
builder = context.createDrawableBuilder(layerPrefix);
|
||||||
builder->setSubLayerIndex(0);
|
builder->setSubLayerIndex(0);
|
||||||
builder->setRenderPass(passes);
|
builder->setRenderPass(passes);
|
||||||
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||||
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
|
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
|
||||||
builder->setColorMode(
|
builder->setColorMode(
|
||||||
((mbgl::underlying_type(passes) & mbgl::underlying_type(RenderPass::Translucent)) != 0)
|
((mbgl::underlying_type(passes) & mbgl::underlying_type(RenderPass::Translucent)) != 0)
|
||||||
? gfx::ColorMode::alphaBlended()
|
? gfx::ColorMode::alphaBlended()
|
||||||
: gfx::ColorMode::unblended());
|
: gfx::ColorMode::unblended());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
|
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
|
||||||
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
|
shaderGroup->getOrCreateShader(context, propertiesAsUniforms, posOffsetAttribName));
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
builder->setShader(shader);
|
builder->setShader(shader);
|
||||||
|
|
||||||
builder->clearTweakers();
|
builder->clearTweakers();
|
||||||
builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker);
|
builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker);
|
||||||
builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4);
|
builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4);
|
||||||
builder->setDrawableName(layerPrefix + std::string(suffix));
|
builder->setDrawableName(layerPrefix + std::string(suffix));
|
||||||
builder->setVertexAttributes(attribs);
|
builder->setVertexAttributes(attribs);
|
||||||
|
|
||||||
if (segments.empty()) {
|
if (segments.empty()) {
|
||||||
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
|
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
|
||||||
} else {
|
} else {
|
||||||
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, segments.data(), segments.size());
|
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, segments.data(), segments.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder->flush(context);
|
builder->flush(context);
|
||||||
|
|
||||||
for (auto& drawable : builder->clearDrawables()) {
|
for (auto& drawable : builder->clearDrawables()) {
|
||||||
drawable->setTileID(tileID);
|
drawable->setTileID(tileID);
|
||||||
drawable->setLayerTweaker(layerTweaker);
|
drawable->setLayerTweaker(layerTweaker);
|
||||||
|
drawable->setRenderTile(renderTilesOwner, &tile);
|
||||||
|
|
||||||
auto drawData = std::make_unique<gfx::SymbolDrawableData>(
|
PaintPropertyBindersBase& textBinders = bucketPaintProperties.textBinders;
|
||||||
/*.isHalo=*/isHalo,
|
PaintPropertyBindersBase& iconBinders = bucketPaintProperties.iconBinders;
|
||||||
/*.bucketVariablePlacement=*/bucket.hasVariablePlacement,
|
drawable->setBinders(renderable.renderData.bucket, isText ? &textBinders : &iconBinders);
|
||||||
/*.symbolType=*/renderable.type,
|
|
||||||
/*.pitchAlignment=*/values.pitchAlignment,
|
|
||||||
/*.rotationAlignment=*/values.rotationAlignment,
|
|
||||||
/*.placement=*/layout.get<SymbolPlacement>(),
|
|
||||||
/*.textFit=*/layout.get<IconTextFit>());
|
|
||||||
|
|
||||||
const auto tileUBO = buildTileUBO(bucket, *drawData, currentZoom);
|
const bool hasVariablePlacement = bucket.hasVariablePlacement;
|
||||||
drawable->setData(std::move(drawData));
|
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();
|
tileLayerGroup->addDrawable(passes, tileID, std::move(drawable));
|
||||||
drawableUniforms.createOrUpdate(idSymbolTilePropsUBO, &tileUBO, context);
|
++stats.drawablesAdded;
|
||||||
drawableUniforms.set(idSymbolInterpolateUBO, interpUBO);
|
}
|
||||||
|
};
|
||||||
tileLayerGroup->addDrawable(passes, tileID, std::move(drawable));
|
|
||||||
++stats.drawablesAdded;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isText) {
|
if (isText) {
|
||||||
if (bucket.iconsInText) {
|
if (bucket.iconsInText) {
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
#include <mbgl/gfx/symbol_drawable_data.hpp>
|
#include <mbgl/gfx/symbol_drawable_data.hpp>
|
||||||
#include <mbgl/layout/symbol_projection.hpp>
|
#include <mbgl/layout/symbol_projection.hpp>
|
||||||
#include <mbgl/programs/symbol_program.hpp>
|
#include <mbgl/programs/symbol_program.hpp>
|
||||||
|
#include <mbgl/renderer/buckets/symbol_bucket.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/render_tree.hpp>
|
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||||
|
#include <mbgl/renderer/render_tree.hpp>
|
||||||
#include <mbgl/shaders/shader_program_base.hpp>
|
#include <mbgl/shaders/shader_program_base.hpp>
|
||||||
#include <mbgl/shaders/symbol_layer_ubo.hpp>
|
#include <mbgl/shaders/symbol_layer_ubo.hpp>
|
||||||
#include <mbgl/style/layers/symbol_layer_properties.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});
|
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
|
} // namespace
|
||||||
|
|
||||||
void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters& parameters) {
|
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());
|
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const auto zoom = static_cast<float>(state.getZoom());
|
||||||
|
|
||||||
if (!evaluatedPropsUniformBuffer || propertiesUpdated) {
|
if (!evaluatedPropsUniformBuffer || propertiesUpdated) {
|
||||||
const SymbolEvaluatedPropsUBO propsUBO = {/*.text_fill_color=*/constOrDefault<TextColor>(evaluated),
|
const SymbolEvaluatedPropsUBO propsUBO = {/*.text_fill_color=*/constOrDefault<TextColor>(evaluated),
|
||||||
/*.text_halo_color=*/constOrDefault<TextHaloColor>(evaluated),
|
/*.text_halo_color=*/constOrDefault<TextHaloColor>(evaluated),
|
||||||
/*.text_opacity=*/constOrDefault<TextOpacity>(evaluated),
|
/*.text_opacity=*/constOrDefault<TextOpacity>(evaluated),
|
||||||
/*.text_halo_width=*/constOrDefault<TextHaloWidth>(evaluated),
|
/*.text_halo_width=*/constOrDefault<TextHaloWidth>(evaluated),
|
||||||
/*.text_halo_blur=*/constOrDefault<TextHaloBlur>(evaluated),
|
/*.text_halo_blur=*/constOrDefault<TextHaloBlur>(evaluated),
|
||||||
0,
|
/* pad */ 0,
|
||||||
/*.icon_fill_color=*/constOrDefault<IconColor>(evaluated),
|
/*.icon_fill_color=*/constOrDefault<IconColor>(evaluated),
|
||||||
/*.icon_halo_color=*/constOrDefault<IconHaloColor>(evaluated),
|
/*.icon_halo_color=*/constOrDefault<IconHaloColor>(evaluated),
|
||||||
/*.icon_opacity=*/constOrDefault<IconOpacity>(evaluated),
|
/*.icon_opacity=*/constOrDefault<IconOpacity>(evaluated),
|
||||||
/*.icon_halo_width=*/constOrDefault<IconHaloWidth>(evaluated),
|
/*.icon_halo_width=*/constOrDefault<IconHaloWidth>(evaluated),
|
||||||
/*.icon_halo_blur=*/constOrDefault<IconHaloBlur>(evaluated),
|
/*.icon_halo_blur=*/constOrDefault<IconHaloBlur>(evaluated),
|
||||||
0};
|
/* pad */ 0};
|
||||||
context.emplaceOrUpdateUniformBuffer(evaluatedPropsUniformBuffer, &propsUBO);
|
context.emplaceOrUpdateUniformBuffer(evaluatedPropsUniformBuffer, &propsUBO);
|
||||||
propertiesUpdated = false;
|
propertiesUpdated = false;
|
||||||
}
|
}
|
||||||
auto& layerUniforms = layerGroup.mutableUniformBuffers();
|
auto& layerUniforms = layerGroup.mutableUniformBuffers();
|
||||||
layerUniforms.set(idSymbolEvaluatedPropsUBO, evaluatedPropsUniformBuffer);
|
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();
|
const auto camDist = state.getCameraToCenterDistance();
|
||||||
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
visitLayerGroupDrawables(layerGroup, [&](gfx::Drawable& drawable) {
|
||||||
if (!drawable.getTileID() || !drawable.getData()) {
|
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& symbolData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
|
||||||
const auto isText = (symbolData.symbolType == SymbolType::Text);
|
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
|
// from RenderTile::translatedMatrix
|
||||||
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();
|
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();
|
||||||
const auto anchor = isText ? evaluated.get<style::TextTranslateAnchor>()
|
const auto anchor = isText ? evaluated.get<style::TextTranslateAnchor>()
|
||||||
@@ -131,9 +184,36 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
|
|||||||
/*.pad=*/{0},
|
/*.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();
|
auto& drawableUniforms = drawable.mutableUniformBuffers();
|
||||||
drawableUniforms.createOrUpdate(idSymbolDrawableUBO, &drawableUBO, context);
|
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
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
|
#include <mbgl/tile/tile_id.hpp>
|
||||||
|
#include <mbgl/util/containers.hpp>
|
||||||
|
#include <mbgl/util/hash.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -13,14 +16,28 @@ class SymbolLayerTweaker : public LayerTweaker {
|
|||||||
public:
|
public:
|
||||||
SymbolLayerTweaker(std::string id_, Immutable<style::LayerProperties> properties)
|
SymbolLayerTweaker(std::string id_, Immutable<style::LayerProperties> properties)
|
||||||
: LayerTweaker(std::move(id_), properties) {}
|
: LayerTweaker(std::move(id_), properties) {}
|
||||||
|
|
||||||
public:
|
|
||||||
~SymbolLayerTweaker() override = default;
|
~SymbolLayerTweaker() override = default;
|
||||||
|
|
||||||
void execute(LayerGroupBase&, const PaintParameters&) override;
|
void execute(LayerGroupBase&, const PaintParameters&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gfx::UniformBufferPtr evaluatedPropsUniformBuffer;
|
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
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -717,11 +717,13 @@ struct InterpolationUniform {
|
|||||||
static constexpr auto name() { return concat_literals<&Attr::name, &string_literal<'_', 't'>::value>::value(); }
|
static constexpr auto name() { return concat_literals<&Attr::name, &string_literal<'_', 't'>::value>::value(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PaintPropertyBindersBase {};
|
||||||
|
|
||||||
template <class Ps>
|
template <class Ps>
|
||||||
class PaintPropertyBinders;
|
class PaintPropertyBinders;
|
||||||
|
|
||||||
template <class... Ps>
|
template <class... Ps>
|
||||||
class PaintPropertyBinders<TypeList<Ps...>> {
|
class PaintPropertyBinders<TypeList<Ps...>> : public PaintPropertyBindersBase {
|
||||||
private:
|
private:
|
||||||
template <class T, class PossiblyEvaluatedType, class... As>
|
template <class T, class PossiblyEvaluatedType, class... As>
|
||||||
struct Detail;
|
struct Detail;
|
||||||
@@ -774,7 +776,7 @@ public:
|
|||||||
|
|
||||||
void setPatternParameters(const std::optional<ImagePosition>& posA,
|
void setPatternParameters(const std::optional<ImagePosition>& posA,
|
||||||
const std::optional<ImagePosition>& posB,
|
const std::optional<ImagePosition>& posB,
|
||||||
const CrossfadeParameters& crossfade) const {
|
const CrossfadeParameters& crossfade) {
|
||||||
util::ignore({(binders.template get<Ps>()->setPatternParameters(posA, posB, crossfade), 0)...});
|
util::ignore({(binders.template get<Ps>()->setPatternParameters(posA, posB, crossfade), 0)...});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ using namespace style;
|
|||||||
|
|
||||||
RenderLayer::RenderLayer(Immutable<style::LayerProperties> properties)
|
RenderLayer::RenderLayer(Immutable<style::LayerProperties> properties)
|
||||||
: evaluatedProperties(std::move(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) {
|
void RenderLayer::transition(const TransitionParameters& parameters, Immutable<style::Layer::Impl> newImpl) {
|
||||||
baseImpl = std::move(newImpl);
|
baseImpl = std::move(newImpl);
|
||||||
@@ -58,6 +59,7 @@ void RenderLayer::prepare(const LayerPrepareParameters& params) {
|
|||||||
assert(params.source);
|
assert(params.source);
|
||||||
assert(params.source->isEnabled());
|
assert(params.source->isEnabled());
|
||||||
renderTiles = params.source->getRenderTiles();
|
renderTiles = params.source->getRenderTiles();
|
||||||
|
renderTilesOwner = params.source->getRawRenderTiles();
|
||||||
addRenderPassesFromTiles();
|
addRenderPassesFromTiles();
|
||||||
|
|
||||||
#if MLN_DRAWABLE_RENDERER
|
#if MLN_DRAWABLE_RENDERER
|
||||||
|
|||||||
@@ -276,6 +276,9 @@ protected:
|
|||||||
// Stores current set of tiles to be rendered for this layer.
|
// Stores current set of tiles to be rendered for this layer.
|
||||||
RenderTiles renderTiles;
|
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
|
// Stores what render passes this layer is currently enabled for. This depends on the
|
||||||
// evaluated StyleProperties object and is updated accordingly.
|
// evaluated StyleProperties object and is updated accordingly.
|
||||||
RenderPass passes = RenderPass::None;
|
RenderPass passes = RenderPass::None;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#include <mbgl/renderer/render_source.hpp>
|
#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/render_source_observer.hpp>
|
||||||
#include <mbgl/renderer/sources/render_geojson_source.hpp>
|
#include <mbgl/renderer/sources/render_geojson_source.hpp>
|
||||||
#include <mbgl/renderer/sources/render_raster_source.hpp>
|
#include <mbgl/renderer/sources/render_raster_source.hpp>
|
||||||
#include <mbgl/renderer/sources/render_raster_dem_source.hpp>
|
#include <mbgl/renderer/sources/render_raster_dem_source.hpp>
|
||||||
#include <mbgl/renderer/sources/render_vector_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_image_source.hpp>
|
||||||
#include <mbgl/renderer/sources/render_custom_geometry_source.hpp>
|
#include <mbgl/renderer/sources/render_custom_geometry_source.hpp>
|
||||||
|
#include <mbgl/renderer/tile_parameters.hpp>
|
||||||
#include <mbgl/tile/tile.hpp>
|
#include <mbgl/tile/tile.hpp>
|
||||||
|
|
||||||
#include <mbgl/layermanager/layer_manager.hpp>
|
|
||||||
#include <mbgl/util/constants.hpp>
|
#include <mbgl/util/constants.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -91,4 +91,8 @@ uint8_t RenderSource::getMaxZoom() const {
|
|||||||
return util::TERRAIN_RGB_MAXZOOM;
|
return util::TERRAIN_RGB_MAXZOOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Immutable<std::vector<RenderTile>> RenderSource::getRawRenderTiles() const {
|
||||||
|
return makeMutable<std::vector<RenderTile>>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public:
|
|||||||
// If supported, returns pointer to image data; returns nullptr otherwise.
|
// If supported, returns pointer to image data; returns nullptr otherwise.
|
||||||
virtual const ImageSourceRenderData* getImageRenderData() const { return nullptr; }
|
virtual const ImageSourceRenderData* getImageRenderData() const { return nullptr; }
|
||||||
virtual const Tile* getRenderedTile(const UnwrappedTileID&) 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(
|
virtual std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures(
|
||||||
const ScreenLineString& geometry,
|
const ScreenLineString& geometry,
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
#include <mbgl/renderer/render_tile.hpp>
|
#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/buckets/debug_bucket.hpp>
|
||||||
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/render_source.hpp>
|
#include <mbgl/renderer/render_source.hpp>
|
||||||
#include <mbgl/renderer/render_static_data.hpp>
|
#include <mbgl/renderer/render_static_data.hpp>
|
||||||
#include <mbgl/renderer/tile_render_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/geometry_tile.hpp>
|
||||||
|
#include <mbgl/tile/tile.hpp>
|
||||||
#include <mbgl/util/math.hpp>
|
#include <mbgl/util/math.hpp>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public:
|
|||||||
RenderTiles getRenderTiles() const override;
|
RenderTiles getRenderTiles() const override;
|
||||||
RenderTiles getRenderTilesSortedByYPosition() const override;
|
RenderTiles getRenderTilesSortedByYPosition() const override;
|
||||||
const Tile* getRenderedTile(const UnwrappedTileID&) 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(
|
std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures(
|
||||||
const ScreenLineString& geometry,
|
const ScreenLineString& geometry,
|
||||||
|
|||||||
Reference in New Issue
Block a user