docs pass

This commit is contained in:
Aiden
2026-05-12 20:32:32 +10:00
parent 3e45bba54b
commit 0a1fe440d9
3 changed files with 31 additions and 4 deletions

View File

@@ -21,6 +21,7 @@ InputFrameMailbox
owns latest disposable CPU input slots owns latest disposable CPU input slots
drops older unsampled input frames when newer frames arrive drops older unsampled input frames when newer frames arrive
protects the one frame currently being uploaded by render protects the one frame currently being uploaded by render
uses a single contiguous copy when capture row stride matches mailbox row stride
SystemFrameExchange SystemFrameExchange
owns Free / Rendering / Completed / Scheduled slots owns Free / Rendering / Completed / Scheduled slots
@@ -46,6 +47,7 @@ Included now:
- simple smooth-motion renderer - simple smooth-motion renderer
- BGRA8-only output - BGRA8-only output
- non-blocking latest-frame input mailbox - non-blocking latest-frame input mailbox
- fast contiguous mailbox copy path for matching input row strides
- render-thread-owned input texture upload - render-thread-owned input texture upload
- async PBO readback - async PBO readback
- latest-N system-memory frame exchange - latest-N system-memory frame exchange
@@ -120,6 +122,7 @@ This tracks parity with `apps/LoopThroughWithOpenGLCompositing`.
- [x] Optional DeckLink input capture - [x] Optional DeckLink input capture
- [x] UYVY8 input capture with render-thread GPU decode to shader input texture - [x] UYVY8 input capture with render-thread GPU decode to shader input texture
- [x] Latest-frame CPU input mailbox - [x] Latest-frame CPU input mailbox
- [x] Fast contiguous input mailbox copy when source/destination stride matches
- [x] Render-owned input texture upload - [x] Render-owned input texture upload
- [x] Runtime shaders receive input through `gVideoInput` - [x] Runtime shaders receive input through `gVideoInput`
- [x] Live DeckLink input bound to `gVideoInput` - [x] Live DeckLink input bound to `gVideoInput`
@@ -251,7 +254,7 @@ Startup order is:
4. start `DeckLinkInputThread` 4. start `DeckLinkInputThread`
5. leave input absent if discovery, setup, format support, or stream startup fails 5. leave input absent if discovery, setup, format support, or stream startup fails
`DeckLinkInput` and `DeckLinkInputThread` are deliberately narrow. They capture BGRA8 frames directly or raw UYVY8 frames into `InputFrameMailbox`; they do not call GL, render, preview, screenshot, shader, or output scheduling code. UYVY8-to-RGBA decode happens later inside the render-thread-owned input texture upload path, so the DeckLink callback stays a capture/copy edge only. Unsupported input modes or formats outside BGRA8/UYVY8 are reported explicitly and treated as an unavailable edge rather than silently converted. `DeckLinkInput` and `DeckLinkInputThread` are deliberately narrow. They capture BGRA8 frames directly or raw UYVY8 frames into `InputFrameMailbox`; they do not call GL, render, preview, screenshot, shader, or output scheduling code. UYVY8-to-RGBA decode happens later inside the render-thread-owned input texture upload path, so the DeckLink callback stays a capture/copy edge only. The mailbox uses one contiguous copy when the capture row stride matches the configured mailbox row stride, and falls back to row-by-row copy only for padded or mismatched frames. Unsupported input modes or formats outside BGRA8/UYVY8 are reported explicitly and treated as an unavailable edge rather than silently converted.
The app samples telemetry once per second. The app samples telemetry once per second.
@@ -271,7 +274,7 @@ Input telemetry:
- `inputSignalPresent`: whether any input frame has reached the mailbox - `inputSignalPresent`: whether any input frame has reached the mailbox
- `inputCaptureFps`: DeckLink input callback capture rate - `inputCaptureFps`: DeckLink input callback capture rate
- `inputConvertMs`: input-edge CPU conversion time; expected to remain `0` for BGRA8 and raw UYVY8 capture because UYVY8 decode is render-thread GPU work - `inputConvertMs`: input-edge CPU conversion time; expected to remain `0` for BGRA8 and raw UYVY8 capture because UYVY8 decode is render-thread GPU work
- `inputSubmitMs`: time spent submitting the latest captured/converted input frame to `InputFrameMailbox` - `inputSubmitMs`: time spent copying/submitting the latest captured input frame to `InputFrameMailbox`
- `inputCaptureFormat`: selected DeckLink input format (`BGRA8`, `UYVY8`, or `none`) - `inputCaptureFormat`: selected DeckLink input format (`BGRA8`, `UYVY8`, or `none`)
- `inputNoSignalFrames`: DeckLink callbacks reporting no input source - `inputNoSignalFrames`: DeckLink callbacks reporting no input source
- `inputUnsupportedFrames`: input frames rejected before mailbox submission - `inputUnsupportedFrames`: input frames rejected before mailbox submission
@@ -319,7 +322,7 @@ Current runtime shader support is deliberately limited to stateless full-frame p
Shader source semantics: Shader source semantics:
- `gVideoInput` means the raw latest input frame for every layer. - `gVideoInput` means the latest decoded shader-visible video input for every layer.
- `gLayerInput` means the previous layer output. - `gLayerInput` means the previous layer output.
- the first layer may receive `gLayerInput = gVideoInput`. - the first layer may receive `gLayerInput = gVideoInput`.
- later layers receive `gVideoInput = original input` and `gLayerInput = previous layer`. - later layers receive `gVideoInput = original input` and `gLayerInput = previous layer`.
@@ -379,7 +382,7 @@ This app keeps the same core behavior but splits it into modules that can grow:
- `frames/`: system-memory handoff - `frames/`: system-memory handoff
- `platform/`: COM/Win32/hidden GL context support - `platform/`: COM/Win32/hidden GL context support
- `render/`: cadence thread, clock, and simple renderer - `render/`: cadence thread, clock, and simple renderer
- `frames/InputFrameMailbox`: non-blocking latest-frame CPU input handoff - `frames/InputFrameMailbox`: non-blocking latest-frame CPU input handoff with contiguous-copy fast path for matching row strides
- `render/InputFrameTexture`: render-thread-owned upload of the latest CPU input frame into GL, including raw UYVY8 decode into the shader-visible input texture - `render/InputFrameTexture`: render-thread-owned upload of the latest CPU input frame into GL, including raw UYVY8 decode into the shader-visible input texture
- `render/readback/`: PBO-backed BGRA8 readback and completed-frame publication - `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/RuntimeRenderScene`: render-thread-owned GL scene for ready runtime shader layers

View File

@@ -282,6 +282,24 @@ Lesson:
- test policies such as `one_before_output` or `skip_before_output` - test policies such as `one_before_output` or `skip_before_output`
- prefer latest-input semantics over draining every pending upload - prefer latest-input semantics over draining every pending upload
### CPU Input Conversion Can Be Worse Than Input Copy
When DeckLink input only exposed UYVY8 on the test machine, an initial CPU UYVY-to-BGRA conversion in the input callback measured around a full-frame budget on sampled runs and reduced input cadence dramatically.
Moving the input edge to raw UYVY8 capture changed the ownership:
- DeckLink callback copies raw supported input bytes into `InputFrameMailbox`
- the mailbox keeps latest-frame semantics and uses a contiguous copy when row strides match
- the render thread uploads/decodes UYVY8 into the shader-visible `gVideoInput` texture
- runtime shaders continue to see decoded input, not packed capture bytes
Lesson:
- keep input callbacks as capture/copy edges
- keep GL decode/upload in the render-owned path
- measure input copy, upload, and decode separately
- do not hide expensive format conversion inside the DeckLink callback
### Preview And Screenshot Must Stay Secondary ### Preview And Screenshot Must Stay Secondary
Preview is useful, but DeckLink output is the real-time path. Preview is useful, but DeckLink output is the real-time path.

View File

@@ -58,6 +58,8 @@ It must not:
If no completed frame is available, record the miss and keep the ownership boundary intact. If no completed frame is available, record the miss and keep the ownership boundary intact.
DeckLink input is also an edge, not a renderer. It may capture/copy the latest supported CPU frame into an input mailbox and update input telemetry, but it must not call GL, schedule output, compile shaders, or drive render cadence. Format decode that requires GL belongs to the render-owned input upload path.
## 4. Runtime Build Work Produces Artifacts ## 4. Runtime Build Work Produces Artifacts
Runtime shader work is split into two phases: Runtime shader work is split into two phases:
@@ -112,6 +114,10 @@ Good examples:
- `completedPollMisses` - `completedPollMisses`
- `scheduleFailures` - `scheduleFailures`
- `decklinkBuffered` - `decklinkBuffered`
- `inputCaptureFps`
- `inputSubmitMs`
- `inputUploadMs`
- `inputConvertMs`
- `shaderCommitted` - `shaderCommitted`
- `shaderFailures` - `shaderFailures`