Step 3
This commit is contained in:
@@ -286,8 +286,8 @@ Target shape:
|
||||
void OpenGLComposite::renderEffect()
|
||||
{
|
||||
mRuntimeUpdateController->ProcessRuntimeWork();
|
||||
RenderFrameState frameState = mRenderFrameCoordinator->BuildFrameState(...);
|
||||
mRenderEngine->RenderLayerStack(frameState);
|
||||
const RenderFrameInput frameInput = BuildRenderFrameInput();
|
||||
RenderFrame(frameInput);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@ Phase 1 named the subsystems. Phase 2 added the typed event substrate. Phase 3 m
|
||||
## Status
|
||||
|
||||
- Phase 4 design package: proposed.
|
||||
- Phase 4 implementation: Step 2 started. The existing synchronous `RenderEngine` entrypoints delegate their GL bodies to named `...OnRenderThread(...)` helpers, and preview/screenshot/render-reset requests now pass through a small `RenderCommandQueue` compatibility mailbox. No dedicated render thread exists yet.
|
||||
- Current alignment: the repo has a named frame-state contract and cleaner render-state preparation, but GL work is still entered through multiple paths protected by one shared `CRITICAL_SECTION`.
|
||||
- Phase 4 implementation: Step 3 started. The existing synchronous `RenderEngine` entrypoints delegate their GL bodies to named `...OnRenderThread(...)` helpers, preview/screenshot/render-reset/input-upload/output-render requests pass through a small `RenderCommandQueue` compatibility mailbox, and `RenderEngine` now starts a dedicated render thread for normal runtime GL work.
|
||||
- Current alignment: the repo has a named frame-state contract and cleaner render-state preparation. Normal runtime GL work is routed through the render thread after startup, while startup initialization still runs before the render thread is started.
|
||||
|
||||
Current GL ownership footholds:
|
||||
|
||||
- `RenderEngine` owns GL resources, the current context-binding compatibility shims, a small render command mailbox, and named render-thread helper methods.
|
||||
- `RenderEngine` owns GL resources, a dedicated render thread, the current synchronous compatibility shims, a small render command mailbox, and named render-thread helper methods.
|
||||
- `RenderFrameInput` / `RenderFrameState` provide the frame-state contract that a render thread can consume.
|
||||
- `RenderFrameStateResolver` prepares the render-facing layer state before drawing.
|
||||
- `OpenGLVideoIOBridge` still calls `RenderEngine::TryUploadInputFrame(...)` from the input path and `RenderEngine::RenderOutputFrame(...)` from the output path.
|
||||
- `OpenGLComposite::paintGL(...)`, screenshot capture, input upload, and output rendering still reach GL through `RenderEngine` methods that bind the shared context under `pMutex`.
|
||||
- `OpenGLComposite::paintGL(...)`, screenshot capture, input upload, and output rendering still call synchronous `RenderEngine` methods, but those methods now invoke render-thread work once `OpenGLComposite::Start()` has started the render thread.
|
||||
|
||||
## Why Phase 4 Exists
|
||||
|
||||
@@ -64,10 +64,10 @@ The current code paths that matter most are:
|
||||
|
||||
| Entry point | Current behavior | Phase 4 direction |
|
||||
| --- | --- | --- |
|
||||
| `RenderEngine::TryUploadInputFrame(...)` | attempts to take the GL lock, binds the context, delegates upload to `UploadInputFrameOnRenderThread(...)` | enqueue latest input frame; render thread uploads |
|
||||
| `RenderEngine::RenderOutputFrame(...)` | takes the GL lock, binds the context, delegates render/readback to `RenderOutputFrameOnRenderThread(...)` | render thread executes output frame production |
|
||||
| `RenderEngine::TryPresentPreview(...)` | attempts to take the GL lock and delegates presentation to `PresentPreviewOnRenderThread(...)` | render thread or preview presenter consumes latest completed frame |
|
||||
| `RenderEngine::CaptureOutputFrameRgbaTopDown(...)` | takes the GL lock, binds the context, delegates readback to `CaptureOutputFrameRgbaTopDownOnRenderThread(...)` | screenshot request becomes render-thread command |
|
||||
| `RenderEngine::TryUploadInputFrame(...)` | synchronous compatibility shim; after render-thread startup it queues input upload work and waits for render-thread completion | enqueue latest input frame; render thread uploads without callback-owned GL |
|
||||
| `RenderEngine::RenderOutputFrame(...)` | synchronous compatibility shim; after render-thread startup it queues output render work and waits for render-thread completion | render thread executes output frame production |
|
||||
| `RenderEngine::TryPresentPreview(...)` | synchronous compatibility shim; after render-thread startup it queues preview presentation and waits for render-thread completion | render thread or preview presenter consumes latest completed frame |
|
||||
| `RenderEngine::CaptureOutputFrameRgbaTopDown(...)` | synchronous compatibility shim; after render-thread startup it queues screenshot readback and waits for render-thread completion | screenshot request becomes render-thread command |
|
||||
| `OpenGLVideoIOBridge::UploadInputFrame(...)` | calls render upload directly | push input frame into render queue/mailbox |
|
||||
| `OpenGLVideoIOBridge::RenderScheduledFrame(...)` | calls render output directly from backend path | request/consume render-produced output without callback-owned GL |
|
||||
|
||||
@@ -133,8 +133,10 @@ Current implementation:
|
||||
|
||||
- `RenderCommandQueue` exists as a pure C++ mailbox helper.
|
||||
- Preview present and screenshot capture requests use latest-value coalescing.
|
||||
- Input upload requests use latest-value coalescing. During the compatibility phase the input frame memory is still drained immediately; a real render thread will need copied or otherwise owned frame storage.
|
||||
- Output frame requests use FIFO semantics so scheduled output demand is not collapsed.
|
||||
- Render-local reset requests coalesce to the strongest pending reset scope.
|
||||
- `RenderEngine` drains these commands synchronously as compatibility shims until a dedicated render thread is introduced.
|
||||
- The synchronous compatibility shims submit queued work to the render thread and wait for completion once the render thread is running.
|
||||
|
||||
Possible commands:
|
||||
|
||||
@@ -234,14 +236,23 @@ Start with low-risk commands:
|
||||
- [x] preview present request
|
||||
- [x] screenshot request
|
||||
- [x] render-local reset requests
|
||||
- [x] input upload request
|
||||
- [x] output render request
|
||||
|
||||
Then move input upload and output render requests once the queue and wakeup behavior are proven.
|
||||
The queue and wakeup behavior still need the dedicated render thread before the callbacks stop borrowing the GL context.
|
||||
|
||||
### Step 3. Start A Dedicated Render Thread
|
||||
|
||||
Create the render thread and make it own context binding.
|
||||
|
||||
Transitional behavior may still allow synchronous request/response for output frames. The important change is that the caller waits for render-thread completion rather than taking the GL context itself.
|
||||
- [x] create a dedicated render thread owned by `RenderEngine`
|
||||
- [x] bind the existing GL context on the render thread for normal runtime work
|
||||
- [x] stop the render thread before GL context destruction
|
||||
- [x] keep transitional synchronous request/response for output frames
|
||||
- [x] remove normal runtime dependence on the shared GL `CRITICAL_SECTION`
|
||||
- [x] add timeout/failure behavior for render-thread requests
|
||||
|
||||
Transitional behavior still allows synchronous request/response for output frames. Render-thread requests now fail fast if they cannot begin within the request timeout, and log over-budget tasks that have already started before waiting for safe completion. The important change is that the caller waits for render-thread completion rather than taking the GL context itself.
|
||||
|
||||
### Step 4. Move Input Upload To The Render Thread
|
||||
|
||||
|
||||
Reference in New Issue
Block a user