INput
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m59s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
Aiden
2026-05-12 18:39:08 +10:00
parent 6e32941675
commit 0a8b335048
14 changed files with 822 additions and 24 deletions

View File

@@ -11,10 +11,17 @@ Before adding features here, read the guardrails in [Render Cadence Golden Rules
```text
RenderThread
owns a hidden OpenGL context
polls latest input frames without waiting
uploads input frames into a render-owned GL texture
renders simple BGRA8 motion at selected cadence
queues async PBO readback
publishes completed frames into SystemFrameExchange
InputFrameMailbox
owns latest disposable CPU input slots
drops older unsampled input frames when newer frames arrive
protects the one frame currently being uploaded by render
SystemFrameExchange
owns Free / Rendering / Completed / Scheduled slots
drops old completed unscheduled frames when render needs space
@@ -37,6 +44,9 @@ Included now:
- hidden render-thread-owned OpenGL context
- simple smooth-motion renderer
- BGRA8-only output
- synthetic BGRA8 input producer
- non-blocking latest-frame input mailbox
- render-thread-owned input texture upload
- async PBO readback
- latest-N system-memory frame exchange
- rendered-frame warmup
@@ -55,18 +65,24 @@ Included now:
- JSON serialization for cadence telemetry snapshots
- background logging with `log`, `warning`, and `error` levels
- local HTTP control server matching the OpenAPI route surface
- HTTP layer controls for add, remove, reorder, bypass, shader change, parameter update, and parameter reset
- trigger parameters as latest-pulse controls with shader-visible count/time
- startup config provider for `config/runtime-host.json`
- quiet telemetry health monitor
- non-GL frame-exchange tests
- non-GL input-mailbox tests
Intentionally not included yet:
- DeckLink input
- real DeckLink input capture
- input format conversion
- temporal/history/feedback shader storage
- texture/LUT asset upload
- text-parameter rasterization
- runtime state
- OSC/API control
- OSC control
- persistent control/state writes
- trigger event history for stacked repeated pulses
- preview
- screenshots
- persistence
@@ -99,16 +115,22 @@ This tracks parity with `apps/LoopThroughWithOpenGLCompositing`.
- [x] Startup config loading from `config/runtime-host.json`
- [x] Cadence telemetry JSON
- [x] Health logging for schedule/drop/starvation events
- [x] Runtime parameter updates from HTTP controls
- [x] Layer reorder/bypass/set-shader/update-parameter/reset-parameter HTTP controls
- [x] Trigger parameter pulse count/time for latest trigger events
- [x] Synthetic BGRA8 frame input producer
- [x] Latest-frame CPU input mailbox
- [x] Render-owned input texture upload
- [x] Runtime shaders receive input through `gVideoInput`
- [ ] DeckLink input capture
- [ ] Input frame upload into the render scene
- [ ] Live video input bound to `gVideoInput`
- [ ] Live DeckLink input bound to `gVideoInput`
- [ ] Input format conversion/scaling
- [ ] Temporal history buffers
- [ ] Feedback buffers
- [ ] Texture asset loading and upload
- [ ] LUT asset loading and upload
- [ ] Text parameter rasterization
- [ ] Runtime parameter updates from controls
- [ ] Layer reorder/bypass/set-shader/update-parameter/reset-parameter controls
- [ ] Trigger history/event buffers for overlapping repeated trigger effects
- [ ] Full runtime state store/read model
- [ ] Persistent layer stack/config writes
- [ ] OSC ingress
@@ -256,13 +278,17 @@ Current runtime shader support is deliberately limited to stateless full-frame p
- no feedback storage
- no texture/LUT assets yet
- no text parameters yet
- manifest defaults are used for parameters
- manifest defaults initialize parameters
- HTTP controls can update runtime parameter values without rebuilding GL programs when the shader program is unchanged
- trigger parameters are treated as latest-pulse controls: each press increments the trigger count and records the current runtime time
- repeated trigger history is not stored yet, so effects such as `trigger-ripple` restart from the latest trigger rather than accumulating overlapping ripples
- the first layer receives a small fallback source texture until DeckLink input is added
- stacked layers receive the previous ready layer output through both `gVideoInput` and `gLayerInput`
- the first layer receives the latest synthetic input texture through both `gVideoInput` and `gLayerInput` when input frames are available
- stacked layers receive the original input through `gVideoInput` and the previous ready layer output through `gLayerInput`
The `/api/state` shader list uses the same support rules as runtime shader compilation and reports only packages this app can run today. Unsupported manifest feature sets such as temporal, feedback, texture-backed, font-backed, or text-parameter shaders are hidden from the control UI for now.
Runtime shaders are exposed through `RuntimeLayerModel` as display layers with manifest parameter defaults. The model also records whether each layer has a render-ready artifact. Add/remove POST controls mutate this app-owned model and may start background shader builds.
Runtime shaders are exposed through `RuntimeLayerModel` as display layers with manifest parameter definitions, current parameter values, build status, and render-ready artifacts. POST controls mutate this app-owned model and may start background shader builds when the selected shader changes.
When a layer becomes render-ready, the app publishes the ready render-layer snapshot to the render thread. The render thread owns the GL-side `RuntimeRenderScene`, diffs that snapshot at a frame boundary, queues new or changed pass programs to the shared-context prepare worker, swaps in a full prepared render plan only after every pass is ready, removes obsolete GL programs, and renders ready layers in order. Stacked stateless full-frame shaders render through internal ping-pong targets so each layer can sample the previous layer through `gLayerInput`; multipass shaders route named intermediate outputs through their manifest-declared pass inputs, and the final ready layer renders to the output target.
@@ -314,6 +340,9 @@ This app keeps the same core behavior but splits it into modules that can grow:
- `frames/`: system-memory handoff
- `platform/`: COM/Win32/hidden GL context support
- `render/`: cadence thread, clock, and simple renderer
- `frames/InputFrameMailbox`: non-blocking latest-frame CPU input handoff
- `video/SyntheticInputProducer`: temporary BGRA8 test-pattern producer for proving the frame-input path
- `render/InputFrameTexture`: render-thread-owned upload of the latest CPU input frame into GL
- `render/readback/`: PBO-backed BGRA8 readback and completed-frame publication
- `render/runtime/RuntimeRenderScene`: render-thread-owned GL scene for ready runtime shader layers
- `render/runtime/RuntimeShaderPrepareWorker`: shared-context runtime shader program compile/link worker
@@ -336,4 +365,4 @@ Only after this app matches the probe's smooth output:
3. port runtime snapshots/live state
4. add control services
5. add preview/screenshot from system-memory frames
6. add DeckLink input as a CPU latest-frame mailbox
6. replace synthetic input with DeckLink input capture into the existing CPU latest-frame mailbox