# RenderCadenceCompositor This app is the modular version of the working DeckLink render-cadence probe. Its job is to prove the production-facing foundation before the current compositor's shader/runtime/control features are ported over. ## Architecture ```text RenderThread owns a hidden OpenGL context renders simple BGRA8 motion at selected cadence queues async PBO readback publishes completed frames into SystemFrameExchange SystemFrameExchange owns Free / Rendering / Completed / Scheduled slots drops old completed unscheduled frames when render needs space protects scheduled frames until DeckLink completion DeckLinkOutputThread consumes completed system-memory frames schedules them into DeckLink up to target depth never renders ``` Startup warms up real rendered frames before DeckLink scheduled playback starts. ## Current Scope Included now: - output-only DeckLink - hidden render-thread-owned OpenGL context - simple smooth-motion renderer - BGRA8-only output - async PBO readback - latest-N system-memory frame exchange - rendered-frame warmup - compact telemetry - non-GL frame-exchange tests Intentionally not included yet: - DeckLink input - shader package rendering - runtime state - OSC/API control - preview - screenshots - persistence Those features should be ported only after the cadence spine is stable. ## Build ```powershell cmake --build --preset build-debug --target RenderCadenceCompositor -- /m:1 ``` The executable is: ```text build\vs2022-x64-debug\Debug\RenderCadenceCompositor.exe ``` ## Run Run from VS Code with: ```text Debug RenderCadenceCompositor ``` Or from a terminal: ```powershell build\vs2022-x64-debug\Debug\RenderCadenceCompositor.exe ``` Press Enter to stop. ## Expected Telemetry The app prints one line per second: ```text renderFps=59.9 scheduleFps=59.9 free=7 completed=1 scheduled=4 completedPollMisses=0 scheduleFailures=0 completions=119 late=0 dropped=0 decklinkBuffered=4 scheduleCallMs=0.0 ``` Healthy first-run signs: - visible DeckLink output is smooth - `renderFps` is close to the selected cadence - `scheduleFps` is close to the selected cadence after warmup - `scheduled` stays near 4 - `decklinkBuffered` stays near 4 when available - `late` and `dropped` do not increase continuously - `scheduleFailures` does not increase `completedPollMisses` means the DeckLink scheduling thread woke up before a completed frame was available. It is not a DeckLink playout underrun by itself. Treat it as healthy polling noise when `scheduled`, `decklinkBuffered`, `late`, `dropped`, and `scheduleFailures` remain stable. ## Baseline Result Date: 2026-05-12 User-visible result: - output was smooth - DeckLink held a 4-frame buffer Representative telemetry: ```text renderFps=59.9 scheduleFps=59.9 free=8 completed=0 scheduled=4 completedPollMisses=30 scheduleFailures=0 completions=720 late=0 dropped=0 decklinkBuffered=4 scheduleCallMs=1.2 renderFps=59.8 scheduleFps=59.8 free=7 completed=1 scheduled=4 completedPollMisses=36 scheduleFailures=0 completions=1080 late=0 dropped=0 decklinkBuffered=4 scheduleCallMs=4.7 renderFps=59.9 scheduleFps=59.9 free=7 completed=1 scheduled=4 completedPollMisses=86 scheduleFailures=0 completions=1381 late=0 dropped=0 decklinkBuffered=4 scheduleCallMs=2.1 ``` Read: - render cadence and DeckLink schedule cadence both held roughly 60 fps - app scheduled depth stayed at 4 - actual DeckLink buffered depth stayed at 4 - no late frames, dropped frames, or schedule failures were observed - completed poll misses were benign because playout remained fully fed ## Tests ```powershell cmake --build --preset build-debug --target RenderCadenceCompositorFrameExchangeTests -- /m:1 ctest --test-dir build\vs2022-x64-debug -C Debug -R RenderCadenceCompositorFrameExchangeTests --output-on-failure ``` ## Relationship To The Probe `apps/DeckLinkRenderCadenceProbe` proved the timing model in one compact file. 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, simple rendering, PBO readback - `video/`: DeckLink output wrapper and scheduling thread - `telemetry/`: cadence telemetry - `app/`: startup/shutdown orchestration ## Next Porting Steps Only after this app matches the probe's smooth output: 1. replace `SimpleMotionRenderer` with a render-scene interface 2. port shader package rendering 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