removed hard coded shader start up
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"previewEnabled": true,
|
||||
"previewFps": 59.94,
|
||||
"runtimeShaderId": "happy-accident",
|
||||
"runtimeShaderId": "",
|
||||
"serverPort": 8080,
|
||||
"shaderLibrary": "shaders"
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@
|
||||
},
|
||||
"runtimeShaderId": {
|
||||
"type": "string",
|
||||
"default": "happy-accident",
|
||||
"description": "Startup shader package id used when no saved runtime layer stack is restored."
|
||||
"default": "",
|
||||
"description": "Optional startup shader package id used only when no saved runtime layer stack is restored. Leave empty to keep the simple fallback renderer until layers are added or restored."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -65,7 +65,7 @@ Do not move DeckLink, NDI, file I/O, shader compilation, or control handling int
|
||||
|
||||
Before cutting a long-lived fork, fix or decide these items:
|
||||
|
||||
- Remove hardcoded `happy-accident` assumptions in `src/app/AppConfig.h` and `src/runtime/shader/RuntimeSlangShaderCompiler.cpp`.
|
||||
- Keep `runtimeShaderId` empty in checked-in config unless this repo intentionally wants a default startup shader again.
|
||||
- Align remaining runtime third-party discovery with CMake. Font atlas generation now checks `MSDF_ATLAS_GEN_ROOT`, `THIRD_PARTY_ROOT`, `3rdParty`, and `video-io-3rdParty`; shader compiler lookup still needs the same treatment for Slang.
|
||||
- Make `config/runtime-host.json` portable. Current checked-in defaults include a local NDI source name and DeckLink output.
|
||||
- Decide whether the fork keeps the Slang shader package contract. If not, retire or clearly isolate `shaders/SHADER_CONTRACT.md`, shader package UI, and shader manifest tests.
|
||||
|
||||
@@ -640,6 +640,8 @@ components:
|
||||
type: number
|
||||
runtimeShaderId:
|
||||
type: string
|
||||
description: Optional startup shader id used only when no saved runtime layer stack is restored.
|
||||
default: ""
|
||||
additionalProperties: false
|
||||
HostVideoInputConfig:
|
||||
type: object
|
||||
|
||||
@@ -62,7 +62,7 @@ Included now:
|
||||
- bounded FIFO system-memory frame exchange
|
||||
- bounded completed-frame output preroll reserve before DeckLink playback, with DeckLink scheduled depth still targeted at four
|
||||
- conservative DeckLink schedule-lead telemetry and recovery
|
||||
- background Slang compile of `shaders/happy-accident`
|
||||
- optional background Slang compile of configured or restored runtime shader layers
|
||||
- app-owned display/render layer model for shader build readiness
|
||||
- app-owned submission of a completed shader artifact
|
||||
- render-thread-owned render-content interface with runtime shader content as the default implementation
|
||||
@@ -364,7 +364,7 @@ Healthy first-run signs:
|
||||
|
||||
## Runtime Slang Shader Stack
|
||||
|
||||
On startup the app first tries to restore `runtime/runtime_state.json`. Valid saved layers are rebuilt in saved order, including shader id, bypass state, and parameter values. Missing shader packages are skipped, invalid saved parameter values fall back to manifest defaults, and if the runtime-state file is missing or unusable the app falls back to the configured shader package. The default configured shader is `shaders/happy-accident`.
|
||||
On startup the app first tries to restore `runtime/runtime_state.json`. Valid saved layers are rebuilt in saved order, including shader id, bypass state, and parameter values. Missing shader packages are skipped, invalid saved parameter values fall back to manifest defaults, and if the runtime-state file is missing or unusable the app falls back to the optional configured startup shader. The checked-in config leaves `runtimeShaderId` empty so a fresh host keeps the simple fallback renderer until layers are added or a saved stack exists.
|
||||
|
||||
The render thread keeps drawing the simple motion renderer while Slang compiles. It does not choose packages, launch Slang, or track build lifecycle. Once a completed shader artifact is published, the render-thread-owned runtime scene queues changed layers to a shared-context GL prepare worker. That worker compiles/links runtime shader programs off the cadence thread. The render thread only swaps in an already-prepared GL program at a frame boundary. If either the Slang build or GL preparation fails, the app keeps rendering the current renderer or simple motion fallback.
|
||||
|
||||
@@ -405,7 +405,7 @@ When a layer becomes render-ready, the app publishes the ready render-layer snap
|
||||
Successful handoff signs:
|
||||
|
||||
- telemetry shows `shaderCommitted=1`
|
||||
- output changes from the simple motion pattern to the Happy Accident shader
|
||||
- output changes from the simple motion pattern to the restored or configured runtime shader stack
|
||||
- render/schedule cadence remains near 60 fps during and after the handoff
|
||||
- DeckLink buffer remains stable
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ AppConfig DefaultAppConfig()
|
||||
config.warmupTimeout = std::chrono::seconds(3);
|
||||
config.prerollTimeout = std::chrono::seconds(3);
|
||||
config.prerollPoll = std::chrono::milliseconds(2);
|
||||
config.runtimeShaderId = "happy-accident";
|
||||
config.runtimeShaderId.clear();
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ struct AppConfig
|
||||
std::chrono::milliseconds warmupTimeout = std::chrono::seconds(3);
|
||||
std::chrono::milliseconds prerollTimeout = std::chrono::seconds(3);
|
||||
std::chrono::milliseconds prerollPoll = std::chrono::milliseconds(2);
|
||||
std::string runtimeShaderId = "happy-accident";
|
||||
std::string runtimeShaderId;
|
||||
};
|
||||
|
||||
AppConfig DefaultAppConfig();
|
||||
|
||||
@@ -36,7 +36,14 @@ void RuntimeLayerController::InitializeLayerModel(std::string& runtimeShaderId)
|
||||
if (InitializeLayerModelFromRuntimeState())
|
||||
return;
|
||||
|
||||
if (!runtimeShaderId.empty())
|
||||
if (runtimeShaderId.empty())
|
||||
{
|
||||
Log("runtime-state", "No saved runtime layer stack or startup shader configured; using fallback renderer.");
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
mRuntimeLayerModel.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
Log("runtime-state", "Falling back to configured runtime shader '" + runtimeShaderId + "'.");
|
||||
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
|
||||
@@ -17,7 +17,7 @@ std::filesystem::path FindRepoRoot()
|
||||
std::filesystem::path current = std::filesystem::current_path();
|
||||
for (;;)
|
||||
{
|
||||
if (std::filesystem::exists(current / "shaders" / "happy-accident" / "shader.slang") &&
|
||||
if (std::filesystem::exists(current / "shaders") &&
|
||||
std::filesystem::exists(current / "runtime" / "templates" / "shader_wrapper.slang.in"))
|
||||
{
|
||||
return current;
|
||||
@@ -49,13 +49,11 @@ RuntimeSlangShaderCompiler::~RuntimeSlangShaderCompiler()
|
||||
Stop();
|
||||
}
|
||||
|
||||
void RuntimeSlangShaderCompiler::StartHappyAccidentBuild()
|
||||
{
|
||||
StartShaderBuild("happy-accident");
|
||||
}
|
||||
|
||||
void RuntimeSlangShaderCompiler::StartShaderBuild(const std::string& shaderId)
|
||||
{
|
||||
if (shaderId.empty())
|
||||
return;
|
||||
|
||||
if (mRunning.load(std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ public:
|
||||
RuntimeSlangShaderCompiler& operator=(const RuntimeSlangShaderCompiler&) = delete;
|
||||
~RuntimeSlangShaderCompiler();
|
||||
|
||||
void StartHappyAccidentBuild();
|
||||
void StartShaderBuild(const std::string& shaderId);
|
||||
void Stop();
|
||||
bool TryConsume(RuntimeSlangShaderBuild& build);
|
||||
|
||||
@@ -165,7 +165,7 @@ void TestKnownPostEndpointReturnsActionError()
|
||||
HttpControlServer::HttpRequest request;
|
||||
request.method = "POST";
|
||||
request.path = "/api/layers/add";
|
||||
request.body = "{\"shaderId\":\"happy-accident\"}";
|
||||
request.body = "{\"shaderId\":\"solid\"}";
|
||||
|
||||
RenderCadenceHttpRouteCallbacks callbacks;
|
||||
const HttpControlServer::HttpResponse response = RouteRenderCadenceHttpRequest(request, server, callbacks);
|
||||
|
||||
@@ -180,6 +180,22 @@ void TestRejectsUnsupportedStartupShader()
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestEmptyStartupShaderKeepsModelEmpty()
|
||||
{
|
||||
std::filesystem::path root;
|
||||
RenderCadenceCompositor::SupportedShaderCatalog catalog = MakeCatalog(root);
|
||||
|
||||
RenderCadenceCompositor::RuntimeLayerModel model;
|
||||
std::string error = "unexpected";
|
||||
Expect(model.InitializeSingleLayer(catalog, "", error), "empty startup shader is accepted");
|
||||
Expect(error.empty(), "empty startup shader reports no error");
|
||||
Expect(model.FirstLayerId().empty(), "empty startup shader creates no startup layer");
|
||||
Expect(model.Snapshot().displayLayers.empty(), "empty startup shader leaves display model empty");
|
||||
Expect(model.PendingLayerBuilds().empty(), "empty startup shader queues no build");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestBuildFailureStaysDisplaySide()
|
||||
{
|
||||
std::filesystem::path root;
|
||||
@@ -576,6 +592,7 @@ int main()
|
||||
{
|
||||
TestSingleLayerLifecycle();
|
||||
TestRejectsUnsupportedStartupShader();
|
||||
TestEmptyStartupShaderKeepsModelEmpty();
|
||||
TestBuildFailureStaysDisplaySide();
|
||||
TestAddAndRemoveLayers();
|
||||
TestSnapshotCompileMessageSummarizesLayerStack();
|
||||
|
||||
@@ -50,6 +50,19 @@ function TextField({ config, label, path, setConfig }) {
|
||||
);
|
||||
}
|
||||
|
||||
function OptionalTextField({ config, label, path, placeholder, setConfig }) {
|
||||
return (
|
||||
<Field label={label}>
|
||||
<input
|
||||
type="text"
|
||||
value={readPath(config, path) ?? ""}
|
||||
placeholder={placeholder}
|
||||
onChange={(event) => setConfig((current) => writePath(current, path, event.target.value))}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
function InputDeviceField({
|
||||
config,
|
||||
manualOpen,
|
||||
@@ -397,7 +410,13 @@ export function ConfigEditor({ onClose }) {
|
||||
<h4>Runtime</h4>
|
||||
<div className="config-fields config-fields--wide">
|
||||
<TextField config={draft} label="Shader library" path="shaderLibrary" setConfig={setDraft} />
|
||||
<TextField config={draft} label="Startup shader" path="runtimeShaderId" setConfig={setDraft} />
|
||||
<OptionalTextField
|
||||
config={draft}
|
||||
label="Startup shader"
|
||||
path="runtimeShaderId"
|
||||
placeholder="restore saved stack"
|
||||
setConfig={setDraft}
|
||||
/>
|
||||
<NumberField config={draft} label="Server port" min={1} path="serverPort" setConfig={setDraft} />
|
||||
<NumberField config={draft} label="Temporal cap" min={0} path="maxTemporalHistoryFrames" setConfig={setDraft} />
|
||||
<ToggleField config={draft} label="Auto reload" path="autoReload" setConfig={setDraft} />
|
||||
|
||||
Reference in New Issue
Block a user