Added config editor in front end
This commit is contained in:
@@ -21,7 +21,7 @@ The app is a native C++ OpenGL compositor with:
|
||||
Primary source areas:
|
||||
|
||||
- `src/app`: startup/shutdown orchestration, config loading, runtime layer controller
|
||||
- `src/render`: cadence clock, input texture upload, simple renderer, readback, and runtime GL support
|
||||
- `src/render`: cadence clock, input texture upload, render-content boundary, readback, and runtime GL support
|
||||
- `src/render/thread`: render thread lifecycle, cadence loop, metrics, and runtime shader commit mailbox
|
||||
- `src/render/runtime`: render-thread-owned runtime shader scene, renderer, text texture upload cache, and shared-context shader prepare worker
|
||||
- `src/frames`: system-memory frame exchange
|
||||
@@ -99,6 +99,8 @@ The mutation path snapshots the current layer model and hands serialized state t
|
||||
|
||||
OSC-driven changes are intentionally not part of this autosave path yet.
|
||||
|
||||
The host configuration editor is separate from runtime layer persistence. The UI reads active and saved startup config through `/api/config`, saves `config/runtime-host.json` through `/api/config/save`, and requests a native host restart through `/api/app/restart`. Render cadence, video input/output selection, resolution, frame rate, output pixel format, HTTP port, and preview settings are still startup-owned; they are not hot-swapped inside the cadence path.
|
||||
|
||||
## Shader Reload
|
||||
|
||||
`POST /api/reload` and the control UI reload button:
|
||||
@@ -129,11 +131,11 @@ The render path consumes published render-layer snapshots. It does not:
|
||||
- handle HTTP or OSC
|
||||
- call DeckLink discovery/setup APIs
|
||||
|
||||
When a runtime shader build completes, the app publishes a render-layer artifact. The render thread-owned runtime scene diffs the snapshot and queues changed pass programs to the shared-context prepare worker. The render thread swaps in an already-prepared render plan at a frame boundary.
|
||||
When a runtime shader build completes, the app publishes a render-layer artifact. The render thread forwards pending layer snapshots to the active render-content adapter. The default `RuntimeShaderRenderContent` owns the runtime scene, diffs the snapshot, and queues changed pass programs to the shared-context prepare worker. The render thread swaps in an already-prepared render plan at a frame boundary through that adapter.
|
||||
|
||||
## Video And Preview
|
||||
|
||||
Video input and output are optional edges. `input.backend` and `output.backend` select the concrete backend through the app-side backend factory. DeckLink is the current concrete backend, and `none` disables that edge. `input` and `output` also carry the device selector plus resolution/frame-rate settings. Configured video modes are represented in `src/video/core` and translated to DeckLink display modes only inside `src/video/decklink`.
|
||||
Video input and output are optional edges. `input.backend` and `output.backend` select the concrete backend through the app-side backend factory. DeckLink and NDI are the current concrete backends, and `none` disables an edge. `input` and `output` also carry the device selector plus resolution/frame-rate settings. Configured video modes are represented in `src/video/core` and translated to backend-specific modes only inside the concrete edge.
|
||||
|
||||
The input edge writes CPU frames into `InputFrameMailbox`. The current DeckLink backend captures BGRA8 directly where possible, or raw UYVY8 for render-thread GPU decode. The input edge does not call GL, render, preview, screenshot, shader, or output scheduling code.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ This note captures the fork-readiness review for using this repository as a base
|
||||
|
||||
The repository is clean enough for an internal fork, but it needs a small hygiene pass before it becomes a comfortable long-lived base repo.
|
||||
|
||||
The important architecture is already in place: render cadence, video input/output, frame exchange, readback, preview, control, and shader build work are mostly separated by role. The main replacement point is the render-thread draw path in `src/render/thread/RenderThread.cpp`, where cadence, input upload, readback, and frame publication wrap the actual GPU rendering call.
|
||||
The important architecture is already in place: render cadence, video input/output, frame exchange, readback, preview, control, and shader build work are mostly separated by role. The main replacement point is the render-content adapter in `src/render/RuntimeShaderRenderContent.*`, where the current shader-package renderer decides what to draw into the framebuffer handed to it by `RenderThread`.
|
||||
|
||||
For a new repo, keep the cadence and frame handoff machinery, then replace or narrow the runtime shader rendering layer.
|
||||
|
||||
@@ -34,22 +34,22 @@ These are most likely to change when the fork renders something other than shade
|
||||
- `runtime/templates/shader_wrapper.slang.in`: only needed for the current Slang package pipeline.
|
||||
- Shader-specific UI affordances in `ui`, if the new renderer has a different control model.
|
||||
|
||||
The cleanest first fork step is to preserve `RenderThread`'s cadence/readback shell and introduce a narrow render-content interface behind the draw call. Then the new repo can swap the implementation without touching video I/O scheduling.
|
||||
The first fork step is now in place: `RenderThread` preserves the cadence/readback shell and calls a narrow render-content interface behind the draw call. A new repo can swap that implementation without touching video I/O scheduling.
|
||||
|
||||
## Current Swap Point
|
||||
|
||||
The current draw decision happens inside the readback queue call in `src/render/thread/RenderThread.cpp`:
|
||||
The render cadence loop now calls `IRenderContent` inside the readback queue call in `src/render/thread/RenderThread.cpp`:
|
||||
|
||||
```cpp
|
||||
if (runtimeRenderScene.HasLayers())
|
||||
runtimeRenderScene.RenderFrame(index, mConfig.width, mConfig.height, videoInputTexture);
|
||||
else if (videoInputTexture != 0)
|
||||
renderer.RenderTexture(videoInputTexture);
|
||||
else
|
||||
renderer.RenderFrame(index);
|
||||
renderContent.RenderFrame(RenderContentFrame{
|
||||
index,
|
||||
mConfig.width,
|
||||
mConfig.height,
|
||||
videoInputTexture
|
||||
});
|
||||
```
|
||||
|
||||
That is the practical boundary for a fork:
|
||||
The default implementation is `RuntimeShaderRenderContent`, which owns the existing runtime shader scene plus simple fallback renderer. That is the practical boundary for a fork:
|
||||
|
||||
- keep the tick clock, input upload, readback queueing, and `SystemFrameExchange` publication around it
|
||||
- replace what draws into the current GL framebuffer
|
||||
@@ -84,9 +84,9 @@ The generated Visual Studio `RUN_TESTS` target did not build missing test execut
|
||||
## Recommended Fork Sequence
|
||||
|
||||
1. Make the hygiene fixes above in this repo or immediately after the fork.
|
||||
2. Add a small render-content abstraction behind the `RenderThread` draw call.
|
||||
3. Port the existing runtime shader renderer behind that abstraction as the baseline implementation.
|
||||
4. Add the new renderer beside it.
|
||||
2. Keep `IRenderContent` as the boundary behind the `RenderThread` draw call.
|
||||
3. Keep `RuntimeShaderRenderContent` as the baseline implementation until the fork's renderer exists.
|
||||
4. Add the new renderer beside it or replace the default adapter.
|
||||
5. Verify that video output still consumes completed frames and never requests rendering directly.
|
||||
6. Only then remove shader package pieces that the new repo no longer needs.
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ servers:
|
||||
tags:
|
||||
- name: State
|
||||
description: Runtime state and status.
|
||||
- name: Config
|
||||
description: Startup host configuration and restart control.
|
||||
- name: Static
|
||||
description: Bundled control UI and static assets served by the local host.
|
||||
- name: Docs
|
||||
@@ -179,6 +181,52 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RuntimeState"
|
||||
/api/config:
|
||||
get:
|
||||
tags: [Config]
|
||||
summary: Get active and saved host config
|
||||
operationId: getHostConfig
|
||||
responses:
|
||||
"200":
|
||||
description: Active startup config and the config currently saved on disk.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/HostConfigResponse"
|
||||
/api/config/save:
|
||||
post:
|
||||
tags: [Config]
|
||||
summary: Save host config
|
||||
description: Saves `runtime-host.json`. Startup-owned services use the new values after app restart.
|
||||
operationId: saveHostConfig
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/HostConfig"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ActionOk"
|
||||
"400":
|
||||
$ref: "#/components/responses/ActionError"
|
||||
/api/app/restart:
|
||||
post:
|
||||
tags: [Config]
|
||||
summary: Restart the native host
|
||||
operationId: restartHost
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ActionOk"
|
||||
"400":
|
||||
$ref: "#/components/responses/ActionError"
|
||||
/ws:
|
||||
get:
|
||||
tags: [State]
|
||||
@@ -511,6 +559,90 @@ components:
|
||||
type: string
|
||||
example: live-show-look
|
||||
additionalProperties: false
|
||||
HostConfigResponse:
|
||||
type: object
|
||||
properties:
|
||||
ok:
|
||||
type: boolean
|
||||
path:
|
||||
type: string
|
||||
active:
|
||||
$ref: "#/components/schemas/HostConfig"
|
||||
disk:
|
||||
$ref: "#/components/schemas/HostConfig"
|
||||
diskLoaded:
|
||||
type: boolean
|
||||
restartRequired:
|
||||
type: boolean
|
||||
error:
|
||||
type: string
|
||||
HostConfig:
|
||||
type: object
|
||||
properties:
|
||||
$schema:
|
||||
type: string
|
||||
shaderLibrary:
|
||||
type: string
|
||||
serverPort:
|
||||
type: number
|
||||
oscBindAddress:
|
||||
type: string
|
||||
oscPort:
|
||||
type: number
|
||||
oscSmoothing:
|
||||
type: number
|
||||
input:
|
||||
$ref: "#/components/schemas/HostVideoInputConfig"
|
||||
output:
|
||||
$ref: "#/components/schemas/HostVideoOutputConfig"
|
||||
autoReload:
|
||||
type: boolean
|
||||
maxTemporalHistoryFrames:
|
||||
type: number
|
||||
previewEnabled:
|
||||
type: boolean
|
||||
previewFps:
|
||||
type: number
|
||||
runtimeShaderId:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
HostVideoInputConfig:
|
||||
type: object
|
||||
properties:
|
||||
backend:
|
||||
type: string
|
||||
enum: [decklink, ndi, none]
|
||||
device:
|
||||
type: string
|
||||
resolution:
|
||||
type: string
|
||||
frameRate:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
HostVideoOutputConfig:
|
||||
type: object
|
||||
properties:
|
||||
backend:
|
||||
type: string
|
||||
enum: [decklink, ndi, none]
|
||||
device:
|
||||
type: string
|
||||
resolution:
|
||||
type: string
|
||||
frameRate:
|
||||
type: string
|
||||
pixelFormat:
|
||||
type: string
|
||||
enum: [auto, bgra8, uyvy8]
|
||||
keying:
|
||||
type: object
|
||||
properties:
|
||||
external:
|
||||
type: boolean
|
||||
alphaRequired:
|
||||
type: boolean
|
||||
additionalProperties: false
|
||||
additionalProperties: false
|
||||
RuntimeState:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user