feat: add STEP-113 Android PBF fast gate diagnostics
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:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mln/renderer/render_segment.hpp>
|
||||
#include <mln/renderer/particle_fast_path.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
@@ -107,11 +108,141 @@ inline void writeStyleLayerDiagnostics(Writer& writer, const StyleLayerDiagnosti
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
inline void writeFastGatePhase(Writer& w, const FastGatePhaseSample& p, const char* phase,
|
||||
const char* placementBasis = "previous-completed-render-tree") {
|
||||
w.StartObject();
|
||||
w.Key("phase"); w.String(phase);
|
||||
w.Key("placementBasis"); w.String(!p.hasPlacementSnapshot ? "UNKNOWN/no-completed-snapshot"
|
||||
: placementBasis);
|
||||
w.Key("placementChanged"); w.Bool(p.placementChanged);
|
||||
w.Key("symbolFadeChange"); w.Double(p.symbolFadeChange);
|
||||
w.Key("placementTransitionActive"); w.Bool(p.placementTransitionActive);
|
||||
w.Key("contentRevision"); w.Uint64(p.contentRevision);
|
||||
w.Key("topologyRevision"); w.Uint64(p.topologyRevision);
|
||||
w.Key("configRevision"); w.Uint64(p.configRevision);
|
||||
w.Key("fullCpuFrame"); w.Uint64(p.fullCpuFrame);
|
||||
w.Key("processSimulationAdvance");
|
||||
if (p.processSimulationAdvance) w.Uint64(*p.processSimulationAdvance); else w.Null();
|
||||
w.Key("retainedSamplesTruncated"); w.Bool(p.retainedSamplesTruncated);
|
||||
w.Key("retained"); w.StartArray();
|
||||
for (const auto& r : p.retained) {
|
||||
const auto& c = r.cache;
|
||||
w.StartObject();
|
||||
w.Key("segmentIndex"); w.Uint(r.segmentIndex);
|
||||
w.Key("cacheState"); w.String(c.cacheState.c_str());
|
||||
w.Key("build"); w.Uint64(c.build);
|
||||
w.Key("reuse"); w.Uint64(c.reuse);
|
||||
w.Key("invalidation"); w.Uint64(c.invalidation);
|
||||
w.Key("fallbackCount"); w.Uint64(c.fallbackCount);
|
||||
w.Key("contentRevision"); w.Uint64(c.contentRevision);
|
||||
w.Key("sourceRevision"); w.Uint64(c.sourceRevision);
|
||||
w.Key("sourceReady"); w.Bool(c.sourceReady);
|
||||
w.Key("sourceStable"); w.Bool(c.sourceStable);
|
||||
w.Key("supported"); w.Bool(c.supported);
|
||||
w.Key("finalDecision"); w.String(c.finalDecision.c_str());
|
||||
w.Key("lastInvalidationReason"); w.String(c.lastInvalidationReason.c_str());
|
||||
w.Key("lastFallbackReason"); w.String(c.lastFallbackReason.c_str());
|
||||
w.Key("placementGatePassed"); w.Bool(r.placementGatePassed);
|
||||
w.Key("actualExecution"); w.String(r.actualExecution.c_str());
|
||||
w.EndObject();
|
||||
}
|
||||
w.EndArray();
|
||||
w.EndObject();
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
inline void writeFastGateTrace(Writer& w, const FastGateTraceDiagnostics& t) {
|
||||
w.StartObject();
|
||||
w.Key("schemaVersion"); w.Uint(t.schemaVersion);
|
||||
w.Key("capacity"); w.Uint(120);
|
||||
w.Key("retainedLimitPerPhase"); w.Uint(16);
|
||||
w.Key("lifecycle"); w.Uint64(t.lifecycle);
|
||||
w.Key("attempts"); w.Uint64(t.attempts);
|
||||
w.Key("overwritten"); w.Uint64(t.overwritten);
|
||||
w.Key("decisionMismatch"); w.Uint64(t.decisionMismatch);
|
||||
w.Key("fullRendered"); w.Uint64(t.fullRendered);
|
||||
w.Key("fastRendered"); w.Uint64(t.fastRendered);
|
||||
w.Key("noRender"); w.Uint64(t.noRender);
|
||||
w.Key("windowCount"); w.Uint(static_cast<unsigned>(t.frames.size()));
|
||||
w.Key("windowBeginSequence"); w.Uint64(t.frames.empty() ? 0 : t.frames.front().sequence);
|
||||
w.Key("windowEndSequence"); w.Uint64(t.frames.empty() ? 0 : t.frames.back().sequence);
|
||||
uint64_t windowFull = 0, windowFast = 0, windowNoRender = 0;
|
||||
std::array<uint64_t, 24> windowFailures{};
|
||||
for (const auto& f : t.frames) {
|
||||
if (f.completed && f.outcome == "full-rendered") ++windowFull;
|
||||
else if (f.completed && f.outcome == "fast-rendered") ++windowFast;
|
||||
else if (f.completed) ++windowNoRender;
|
||||
for (std::size_t i = 0; i < 24; ++i) if (f.failMask & (uint32_t{1} << i)) ++windowFailures[i];
|
||||
}
|
||||
w.Key("windowFullRendered"); w.Uint64(windowFull);
|
||||
w.Key("windowFastRendered"); w.Uint64(windowFast);
|
||||
w.Key("windowNoRender"); w.Uint64(windowNoRender);
|
||||
w.Key("gates"); w.StartArray();
|
||||
for (std::size_t i = 0; i < particleFastGateReasons.size(); ++i) {
|
||||
w.StartObject();
|
||||
w.Key("order"); w.Uint(static_cast<unsigned>(i + 1));
|
||||
w.Key("reason"); w.String(particleFastPathMissReasonText(particleFastGateReasons[i]));
|
||||
w.Key("failures"); w.Uint64(t.failureCounts[i]);
|
||||
w.Key("firstFailures"); w.Uint64(t.firstFailureCounts[i]);
|
||||
w.Key("windowFailures"); w.Uint64(windowFailures[i]);
|
||||
w.EndObject();
|
||||
}
|
||||
w.EndArray();
|
||||
w.Key("frames"); w.StartArray();
|
||||
for (const auto& f : t.frames) {
|
||||
w.StartObject();
|
||||
w.Key("sequence"); w.Uint64(f.sequence);
|
||||
w.Key("frame"); w.Uint64(f.frame);
|
||||
w.Key("updateTimeNs"); w.Int64(f.updateTimeNs);
|
||||
w.Key("knownMask"); w.Uint(f.knownMask);
|
||||
w.Key("failMask"); w.Uint(f.failMask);
|
||||
w.Key("firstFailure"); w.String(f.firstFailure.c_str());
|
||||
w.Key("decisionConsistent"); w.Bool(f.decisionConsistent);
|
||||
w.Key("candidate"); w.Bool(f.candidate);
|
||||
w.Key("preFastPlacementTransition"); w.Bool(f.preFastPlacementTransition);
|
||||
w.Key("placementTransitionsEnabled"); w.Bool(f.placementTransitionsEnabled);
|
||||
w.Key("completed"); w.Bool(f.completed);
|
||||
w.Key("outcome"); w.String(f.outcome.c_str());
|
||||
w.Key("gateStatus"); w.StartArray();
|
||||
for (std::size_t i = 0; i < 24; ++i) {
|
||||
const auto bit = uint32_t{1} << i;
|
||||
w.String(!(f.knownMask & bit) ? "UNKNOWN" : (f.failMask & bit) ? "FAIL" : "PASS");
|
||||
}
|
||||
w.EndArray();
|
||||
w.Key("cacheInputsTruncated"); w.Bool(f.cacheInputsTruncated);
|
||||
w.Key("cacheInputs"); w.StartArray();
|
||||
for (const auto& c : f.cacheInputs) {
|
||||
w.StartObject();
|
||||
w.Key("segmentIndex"); w.Uint(c.segmentIndex);
|
||||
w.Key("exists"); w.Bool(c.exists);
|
||||
w.Key("valid"); w.Bool(c.valid);
|
||||
w.Key("buildRevision"); w.Uint64(c.buildRevision);
|
||||
w.Key("staticRevision"); w.Uint64(c.staticRevision);
|
||||
w.EndObject();
|
||||
}
|
||||
w.EndArray();
|
||||
w.Key("pre"); writeFastGatePhase(w, f.pre, "pre-fast");
|
||||
w.Key("post");
|
||||
if (f.completed) {
|
||||
writeFastGatePhase(w, f.post, "post-render", f.outcome == "full-rendered"
|
||||
? "current-full-render-tree" : f.outcome == "fast-rendered"
|
||||
? "current-fast-render-tree/no-new-placement" : "previous-completed-render-tree");
|
||||
} else w.Null();
|
||||
w.EndObject();
|
||||
}
|
||||
w.EndArray();
|
||||
w.EndObject();
|
||||
}
|
||||
|
||||
inline std::string renderSegmentDiagnosticsToJSON(const RenderSegmentDiagnostics& snapshot) {
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
writer.StartObject();
|
||||
writer.Key("schemaVersion"); writer.Uint(snapshot.schemaVersion);
|
||||
if (snapshot.fastGateTrace) {
|
||||
writer.Key("fastGateTrace"); writeFastGateTrace(writer, *snapshot.fastGateTrace);
|
||||
}
|
||||
writer.Key("enabled"); writer.Bool(snapshot.enabled);
|
||||
writer.Key("configured"); writer.Bool(snapshot.configured);
|
||||
writer.Key("valid"); writer.Bool(snapshot.valid);
|
||||
|
||||
Reference in New Issue
Block a user