Start up settle
This commit is contained in:
@@ -54,6 +54,7 @@ Included now:
|
||||
- async PBO readback
|
||||
- latest-N system-memory frame exchange
|
||||
- rendered-frame warmup
|
||||
- eight completed output warmup frames before DeckLink preroll, with DeckLink scheduled depth still targeted at four
|
||||
- background Slang compile of `shaders/happy-accident`
|
||||
- app-owned display/render layer model for shader build readiness
|
||||
- app-owned submission of a completed shader artifact
|
||||
@@ -198,6 +199,7 @@ Currently consumed fields:
|
||||
- `autoReload`
|
||||
- `maxTemporalHistoryFrames`
|
||||
- `previewFps`
|
||||
- `startupSettleMs`
|
||||
- `enableExternalKeying`
|
||||
|
||||
The loaded config is treated as a read-only startup snapshot. Subsystems that need config should receive this snapshot or a narrowed config struct from app orchestration; they should not reload files independently.
|
||||
|
||||
@@ -29,8 +29,9 @@ AppConfig DefaultAppConfig()
|
||||
config.autoReload = true;
|
||||
config.maxTemporalHistoryFrames = 12;
|
||||
config.previewFps = 30.0;
|
||||
config.warmupCompletedFrames = 4;
|
||||
config.warmupCompletedFrames = 8;
|
||||
config.warmupTimeout = std::chrono::seconds(3);
|
||||
config.startupSettle = std::chrono::seconds(5);
|
||||
config.prerollTimeout = std::chrono::seconds(3);
|
||||
config.prerollPoll = std::chrono::milliseconds(2);
|
||||
config.runtimeShaderId = "happy-accident";
|
||||
|
||||
@@ -30,8 +30,9 @@ struct AppConfig
|
||||
bool autoReload = true;
|
||||
std::size_t maxTemporalHistoryFrames = 12;
|
||||
double previewFps = 30.0;
|
||||
std::size_t warmupCompletedFrames = 4;
|
||||
std::size_t warmupCompletedFrames = 8;
|
||||
std::chrono::milliseconds warmupTimeout = std::chrono::seconds(3);
|
||||
std::chrono::milliseconds startupSettle = std::chrono::seconds(5);
|
||||
std::chrono::milliseconds prerollTimeout = std::chrono::seconds(3);
|
||||
std::chrono::milliseconds prerollPoll = std::chrono::milliseconds(2);
|
||||
std::string runtimeShaderId = "happy-accident";
|
||||
|
||||
@@ -133,6 +133,9 @@ bool AppConfigProvider::Load(const std::filesystem::path& path, std::string& err
|
||||
ApplySize(root, "maxTemporalHistoryFrames", mConfig.maxTemporalHistoryFrames);
|
||||
ApplyDouble(root, "previewFps", mConfig.previewFps);
|
||||
ApplyBool(root, "enableExternalKeying", mConfig.deckLink.externalKeyingEnabled);
|
||||
std::size_t startupSettleMilliseconds = static_cast<std::size_t>(mConfig.startupSettle.count());
|
||||
ApplySize(root, "startupSettleMs", startupSettleMilliseconds);
|
||||
mConfig.startupSettle = std::chrono::milliseconds(startupSettleMilliseconds);
|
||||
|
||||
mLoadedFromFile = true;
|
||||
error.clear();
|
||||
|
||||
@@ -96,6 +96,20 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mConfig.startupSettle > std::chrono::milliseconds::zero())
|
||||
{
|
||||
Log("app", "Settling render cadence before DeckLink output for " + std::to_string(mConfig.startupSettle.count()) + " ms.");
|
||||
std::this_thread::sleep_for(mConfig.startupSettle);
|
||||
Log("app", "Waiting for rendered reserve after startup settle.");
|
||||
if (!mFrameExchange.WaitForCompletedDepth(mConfig.warmupCompletedFrames, mConfig.warmupTimeout))
|
||||
{
|
||||
error = "Timed out waiting for rendered reserve after startup settle.";
|
||||
LogError("app", error);
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
StartOptionalVideoOutput();
|
||||
mTelemetryHealth.Start(mFrameExchange, mOutput, mOutputThread, mRenderThread);
|
||||
StartHttpServer();
|
||||
|
||||
@@ -251,6 +251,7 @@ inline std::string RuntimeStateToJson(const RuntimeStateJsonInput& input)
|
||||
writer.KeyUInt("maxTemporalHistoryFrames", static_cast<uint64_t>(input.config.maxTemporalHistoryFrames));
|
||||
writer.KeyDouble("previewFps", input.config.previewFps);
|
||||
writer.KeyBool("enableExternalKeying", input.config.deckLink.externalKeyingEnabled);
|
||||
writer.KeyUInt("startupSettleMs", static_cast<uint64_t>(input.config.startupSettle.count()));
|
||||
writer.KeyString("inputVideoFormat", input.config.inputVideoFormat);
|
||||
writer.KeyString("inputFrameRate", input.config.inputFrameRate);
|
||||
writer.KeyString("outputVideoFormat", input.config.outputVideoFormat);
|
||||
|
||||
@@ -22,6 +22,8 @@ struct CadenceTelemetrySnapshot
|
||||
uint64_t completions = 0;
|
||||
uint64_t displayedLate = 0;
|
||||
uint64_t dropped = 0;
|
||||
uint64_t clockOverruns = 0;
|
||||
uint64_t clockSkippedFrames = 0;
|
||||
uint64_t shaderBuildsCommitted = 0;
|
||||
uint64_t shaderBuildFailures = 0;
|
||||
uint64_t inputFramesReceived = 0;
|
||||
@@ -104,6 +106,8 @@ public:
|
||||
{
|
||||
CadenceTelemetrySnapshot snapshot = Sample(exchange, output, outputThread);
|
||||
const auto renderMetrics = renderThread.GetMetrics();
|
||||
snapshot.clockOverruns = renderMetrics.clockOverruns;
|
||||
snapshot.clockSkippedFrames = renderMetrics.skippedFrames;
|
||||
snapshot.shaderBuildsCommitted = renderMetrics.shaderBuildsCommitted;
|
||||
snapshot.shaderBuildFailures = renderMetrics.shaderBuildFailures;
|
||||
snapshot.inputFramesReceived = renderMetrics.inputFramesReceived;
|
||||
|
||||
@@ -24,6 +24,10 @@ inline void WriteCadenceTelemetryJson(JsonWriter& writer, const CadenceTelemetry
|
||||
writer.KeyUInt("completions", snapshot.completions);
|
||||
writer.KeyUInt("late", snapshot.displayedLate);
|
||||
writer.KeyUInt("dropped", snapshot.dropped);
|
||||
writer.KeyUInt("clockOverruns", snapshot.clockOverruns);
|
||||
writer.KeyUInt("clockSkippedFrames", snapshot.clockSkippedFrames);
|
||||
writer.KeyUInt("clockOveruns", snapshot.clockOverruns);
|
||||
writer.KeyUInt("clockSkipped", snapshot.clockSkippedFrames);
|
||||
writer.KeyUInt("shaderCommitted", snapshot.shaderBuildsCommitted);
|
||||
writer.KeyUInt("shaderFailures", snapshot.shaderBuildFailures);
|
||||
writer.KeyUInt("inputFramesReceived", snapshot.inputFramesReceived);
|
||||
|
||||
Reference in New Issue
Block a user