4.5 KiB
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
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
cmake --build --preset build-debug --target RenderCadenceCompositor -- /m:1
The executable is:
build\vs2022-x64-debug\Debug\RenderCadenceCompositor.exe
Run
Run from VS Code with:
Debug RenderCadenceCompositor
Or from a terminal:
build\vs2022-x64-debug\Debug\RenderCadenceCompositor.exe
Press Enter to stop.
Expected Telemetry
The app prints one line per second:
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
renderFpsis close to the selected cadencescheduleFpsis close to the selected cadence after warmupscheduledstays near 4decklinkBufferedstays near 4 when availablelateanddroppeddo not increase continuouslyscheduleFailuresdoes 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:
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
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 handoffplatform/: COM/Win32/hidden GL context supportrender/: cadence, simple rendering, PBO readbackvideo/: DeckLink output wrapper and scheduling threadtelemetry/: cadence telemetryapp/: startup/shutdown orchestration
Next Porting Steps
Only after this app matches the probe's smooth output:
- replace
SimpleMotionRendererwith a render-scene interface - port shader package rendering
- port runtime snapshots/live state
- add control services
- add preview/screenshot from system-memory frames
- add DeckLink input as a CPU latest-frame mailbox