test: add core particle render layer validation
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
25
src/mbgl/layermanager/particle_validation_layer_factory.cpp
Normal file
25
src/mbgl/layermanager/particle_validation_layer_factory.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <mbgl/layermanager/particle_validation_layer_factory.hpp>
|
||||
|
||||
#include <mbgl/renderer/layers/render_particle_validation_layer.hpp>
|
||||
#include <mbgl/style/layers/particle_validation_layer.hpp>
|
||||
#include <mbgl/style/layers/particle_validation_layer_impl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
const style::LayerTypeInfo* ParticleValidationLayerFactory::getTypeInfo() const noexcept {
|
||||
return style::ParticleValidationLayer::Impl::staticTypeInfo();
|
||||
}
|
||||
|
||||
std::unique_ptr<style::Layer> ParticleValidationLayerFactory::createLayer(
|
||||
const std::string& id, const style::conversion::Convertible&) noexcept {
|
||||
return std::make_unique<style::ParticleValidationLayer>(id);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderLayer> ParticleValidationLayerFactory::createRenderLayer(
|
||||
Immutable<style::Layer::Impl> impl) noexcept {
|
||||
assert(impl->getTypeInfo() == getTypeInfo());
|
||||
return std::make_unique<RenderParticleValidationLayer>(
|
||||
staticImmutableCast<style::ParticleValidationLayer::Impl>(impl));
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
132
src/mbgl/renderer/layers/render_particle_validation_layer.cpp
Normal file
132
src/mbgl/renderer/layers/render_particle_validation_layer.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include <mbgl/renderer/layers/render_particle_validation_layer.hpp>
|
||||
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/gfx/drawable_tweaker.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace {
|
||||
const style::ParticleValidationLayer::Impl& impl(const Immutable<style::Layer::Impl>& value) {
|
||||
assert(value->getTypeInfo() == style::ParticleValidationLayer::Impl::staticTypeInfo());
|
||||
return static_cast<const style::ParticleValidationLayer::Impl&>(*value);
|
||||
}
|
||||
|
||||
class ParticleValidationDrawableTweaker final : public gfx::DrawableTweaker {
|
||||
public:
|
||||
ParticleValidationDrawableTweaker(std::string id_, bool active_, int32_t layerIndex_)
|
||||
: id(std::move(id_)),
|
||||
active(active_),
|
||||
layerIndex(layerIndex_) {}
|
||||
|
||||
~ParticleValidationDrawableTweaker() override {
|
||||
Log::Info(Event::Render,
|
||||
"ParticleValidation: validation drawable destroy id=" + id +
|
||||
" validationFrames=" + std::to_string(validationFrameCount));
|
||||
}
|
||||
|
||||
void init(gfx::Drawable&) override {}
|
||||
|
||||
void execute(gfx::Drawable&, PaintParameters& parameters) override {
|
||||
if (parameters.pass != RenderPass::Translucent) {
|
||||
return;
|
||||
}
|
||||
|
||||
++validationFrameCount;
|
||||
if (validationFrameCount != 1 && validationFrameCount % 60 != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto size = parameters.state.getSize();
|
||||
const auto& matrix = parameters.transformParams.projMatrix;
|
||||
std::ostringstream message;
|
||||
message << "ParticleValidation: render frame=" << validationFrameCount << " mapFrame=" << parameters.frameCount
|
||||
<< " state=" << (active ? "ACTIVE" : "STATIC") << " repaint=" << (active ? "requested" : "stopped")
|
||||
<< " pass=translucent" << " layerIndex=" << layerIndex << " currentLayer=" << parameters.currentLayer
|
||||
<< " viewport=" << size.width << 'x' << size.height << " zoom=" << parameters.state.getZoom()
|
||||
<< " bearing=" << parameters.state.getBearing() << " pitch=" << parameters.state.getPitch() << " proj=["
|
||||
<< matrix[0] << ',' << matrix[5] << ',' << matrix[12] << ',' << matrix[13] << ']';
|
||||
Log::Info(Event::Render, message.str());
|
||||
}
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
bool active;
|
||||
int32_t layerIndex;
|
||||
uint64_t validationFrameCount = 0;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
RenderParticleValidationLayer::RenderParticleValidationLayer(Immutable<style::ParticleValidationLayer::Impl> impl_)
|
||||
: RenderLayer(makeMutable<style::ParticleValidationLayerProperties>(impl_, impl_->active)) {
|
||||
Log::Info(Event::Render,
|
||||
"ParticleValidation: RenderLayer create id=" + getID() + " source-less=true pass=translucent");
|
||||
}
|
||||
|
||||
RenderParticleValidationLayer::~RenderParticleValidationLayer() {
|
||||
Log::Info(Event::Render, "ParticleValidation: RenderLayer destroy id=" + getID());
|
||||
}
|
||||
|
||||
void RenderParticleValidationLayer::evaluate(const PropertyEvaluationParameters&) {
|
||||
const bool active = impl(baseImpl).active;
|
||||
auto properties = makeMutable<style::ParticleValidationLayerProperties>(
|
||||
staticImmutableCast<style::ParticleValidationLayer::Impl>(baseImpl), active);
|
||||
passes = RenderPass::Translucent;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
Log::Info(Event::Render,
|
||||
"ParticleValidation: state=" + std::string(active ? "ACTIVE" : "STATIC") + " id=" + getID() +
|
||||
" layerIndex=" + std::to_string(getLayerIndex()));
|
||||
}
|
||||
|
||||
bool RenderParticleValidationLayer::needsRepaint() const {
|
||||
const auto& properties = static_cast<const style::ParticleValidationLayerProperties&>(*evaluatedProperties);
|
||||
return properties.active && baseImpl->visibility != style::VisibilityType::None;
|
||||
}
|
||||
|
||||
void RenderParticleValidationLayer::update(gfx::ShaderRegistry&,
|
||||
gfx::Context& context,
|
||||
const TransformState&,
|
||||
const std::shared_ptr<UpdateParameters>&,
|
||||
const RenderTree&,
|
||||
UniqueChangeRequestVec& changes) {
|
||||
if (!layerGroup) {
|
||||
if (auto group = context.createLayerGroup(layerIndex, 1, getID())) {
|
||||
setLayerGroup(std::move(group), changes);
|
||||
}
|
||||
}
|
||||
if (!layerGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* group = static_cast<LayerGroup*>(layerGroup.get());
|
||||
if (group->getDrawableCount() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool active = static_cast<const style::ParticleValidationLayerProperties&>(*evaluatedProperties).active;
|
||||
auto builder = context.createDrawableBuilder(getID());
|
||||
auto& drawable = builder->getCurrentDrawable(true);
|
||||
drawable->setIsCustom(true);
|
||||
drawable->setRenderPass(RenderPass::Translucent);
|
||||
drawable->addTweaker(std::make_shared<ParticleValidationDrawableTweaker>(getID(), active, getLayerIndex()));
|
||||
auto drawables = builder->clearDrawables();
|
||||
group->addDrawable(std::move(drawables.front()));
|
||||
++stats.drawablesAdded;
|
||||
|
||||
Log::Info(Event::Render,
|
||||
"ParticleValidation: validation drawable create id=" + getID() +
|
||||
" layerIndex=" + std::to_string(getLayerIndex()) + " pass=translucent");
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/style/layers/particle_validation_layer_impl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// VALIDATION ONLY: proves Core RenderLayer/frame-transform/repaint integration.
|
||||
class RenderParticleValidationLayer final : public RenderLayer {
|
||||
public:
|
||||
explicit RenderParticleValidationLayer(Immutable<style::ParticleValidationLayer::Impl>);
|
||||
~RenderParticleValidationLayer() override;
|
||||
|
||||
void update(gfx::ShaderRegistry&,
|
||||
gfx::Context&,
|
||||
const TransformState&,
|
||||
const std::shared_ptr<UpdateParameters>&,
|
||||
const RenderTree&,
|
||||
UniqueChangeRequestVec&) override;
|
||||
|
||||
private:
|
||||
void transition(const TransitionParameters&) override {}
|
||||
void evaluate(const PropertyEvaluationParameters&) override;
|
||||
bool hasTransition() const override { return false; }
|
||||
bool hasCrossfade() const override { return false; }
|
||||
bool needsRepaint() const override;
|
||||
void prepare(const LayerPrepareParameters&) override {}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -106,6 +106,9 @@ public:
|
||||
// Returns true if the layer has a pattern property and is actively crossfading.
|
||||
virtual bool hasCrossfade() const = 0;
|
||||
|
||||
// Returns true when an active animated layer needs another MapLibre frame.
|
||||
virtual bool needsRepaint() const { return false; }
|
||||
|
||||
// Returns true if layer writes to depth buffer by drawing using PaintParameters::depthModeFor3D().
|
||||
virtual bool is3D() const { return false; }
|
||||
|
||||
|
||||
@@ -818,7 +818,7 @@ bool RenderOrchestrator::hasTransitions(TimePoint timePoint) const {
|
||||
}
|
||||
|
||||
for (const auto& entry : renderLayers) {
|
||||
if (entry.second->hasTransition()) {
|
||||
if (entry.second->hasTransition() || entry.second->needsRepaint()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
110
src/mbgl/style/layers/particle_validation_layer.cpp
Normal file
110
src/mbgl/style/layers/particle_validation_layer.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include <mbgl/style/layers/particle_validation_layer.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/constant.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/layer_observer.hpp>
|
||||
#include <mbgl/style/layers/particle_validation_layer_impl.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
namespace {
|
||||
constexpr const char* ActiveProperty = "particle-validation-active";
|
||||
|
||||
const LayerTypeInfo typeInfo{.type = "particle-validation",
|
||||
.source = LayerTypeInfo::Source::NotRequired,
|
||||
.pass3d = LayerTypeInfo::Pass3D::NotRequired,
|
||||
.layout = LayerTypeInfo::Layout::NotRequired,
|
||||
.fadingTiles = LayerTypeInfo::FadingTiles::NotRequired,
|
||||
.crossTileIndex = LayerTypeInfo::CrossTileIndex::NotRequired,
|
||||
.tileKind = LayerTypeInfo::TileKind::NotRequired};
|
||||
} // namespace
|
||||
|
||||
ParticleValidationLayer::Impl::Impl(const std::string& id)
|
||||
: Layer::Impl(id, std::string()) {}
|
||||
|
||||
bool ParticleValidationLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParticleValidationLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {}
|
||||
|
||||
const LayerTypeInfo* ParticleValidationLayer::Impl::staticTypeInfo() noexcept {
|
||||
return &typeInfo;
|
||||
}
|
||||
|
||||
ParticleValidationLayer::ParticleValidationLayer(const std::string& layerID)
|
||||
: Layer(makeMutable<Impl>(layerID)) {
|
||||
Log::Info(Event::Render, "ParticleValidation: Style Layer create id=" + layerID + " (VALIDATION ONLY)");
|
||||
}
|
||||
|
||||
ParticleValidationLayer::ParticleValidationLayer(Immutable<Impl> impl_)
|
||||
: Layer(std::move(impl_)) {}
|
||||
|
||||
ParticleValidationLayer::~ParticleValidationLayer() {
|
||||
Log::Info(Event::Render, "ParticleValidation: Style Layer destroy id=" + getID());
|
||||
weakFactory.invalidateWeakPtrs();
|
||||
}
|
||||
|
||||
const ParticleValidationLayer::Impl& ParticleValidationLayer::impl() const {
|
||||
return static_cast<const Impl&>(*baseImpl);
|
||||
}
|
||||
|
||||
Mutable<ParticleValidationLayer::Impl> ParticleValidationLayer::mutableImpl() const {
|
||||
return makeMutable<Impl>(impl());
|
||||
}
|
||||
|
||||
bool ParticleValidationLayer::isActive() const {
|
||||
return impl().active;
|
||||
}
|
||||
|
||||
void ParticleValidationLayer::setActive(bool active) {
|
||||
if (active == isActive()) {
|
||||
return;
|
||||
}
|
||||
auto impl_ = mutableImpl();
|
||||
impl_->active = active;
|
||||
baseImpl = std::move(impl_);
|
||||
observer->onLayerChanged(*this);
|
||||
}
|
||||
|
||||
std::optional<conversion::Error> ParticleValidationLayer::setPropertyInternal(const std::string& name,
|
||||
const conversion::Convertible& value) {
|
||||
if (name != ActiveProperty) {
|
||||
return conversion::Error{"layer doesn't support this property"};
|
||||
}
|
||||
conversion::Error error;
|
||||
auto converted = conversion::convert<bool>(value, error);
|
||||
if (!converted) {
|
||||
return error;
|
||||
}
|
||||
setActive(*converted);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
StyleProperty ParticleValidationLayer::getProperty(const std::string& name) const {
|
||||
if (name == ActiveProperty) {
|
||||
return StyleProperty(Value{isActive()}, StyleProperty::Kind::Constant);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Value ParticleValidationLayer::serialize() const {
|
||||
auto result = Layer::serialize();
|
||||
serializeProperty(result, getProperty(ActiveProperty), ActiveProperty, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Layer> ParticleValidationLayer::cloneRef(const std::string& id) const {
|
||||
auto impl_ = mutableImpl();
|
||||
impl_->id = id;
|
||||
return std::unique_ptr<Layer>(new ParticleValidationLayer(std::move(impl_)));
|
||||
}
|
||||
|
||||
Mutable<Layer::Impl> ParticleValidationLayer::mutableBaseImpl() const {
|
||||
return staticMutableCast<Layer::Impl>(mutableImpl());
|
||||
}
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
36
src/mbgl/style/layers/particle_validation_layer_impl.hpp
Normal file
36
src/mbgl/style/layers/particle_validation_layer_impl.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/style/layer_properties.hpp>
|
||||
#include <mbgl/style/layers/particle_validation_layer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
// VALIDATION ONLY: no particle data or production API belongs here.
|
||||
class ParticleValidationLayer::Impl final : public Layer::Impl {
|
||||
public:
|
||||
explicit Impl(const std::string& id);
|
||||
Impl(const Impl&) = default;
|
||||
|
||||
bool hasLayoutDifference(const Layer::Impl&) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
bool active = true;
|
||||
|
||||
DECLARE_LAYER_TYPE_INFO;
|
||||
};
|
||||
|
||||
class ParticleValidationLayerProperties final : public LayerProperties {
|
||||
public:
|
||||
ParticleValidationLayerProperties(Immutable<ParticleValidationLayer::Impl> impl, bool active_)
|
||||
: LayerProperties(std::move(impl)),
|
||||
active(active_) {}
|
||||
|
||||
expression::Dependency getDependencies() const noexcept override { return expression::Dependency::None; }
|
||||
|
||||
bool active;
|
||||
};
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user