refactor(render): compose render frame orchestrator

Move the accepted draw transaction and failure recovery behind typed frame-phase owners so GameWindow only supplies immutable frame input. Preserve retail draw order, make ImGui/bootstrap shutdown ownership explicit, and restore exact text-render GL state on failures.\n\nCo-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-22 08:03:49 +02:00
parent 28e1cf8029
commit 9d7df1bfc5
25 changed files with 1675 additions and 279 deletions

View file

@ -28,7 +28,7 @@ port, or resource-lifetime redesign.
`RetailPViewPassExecutor` and data-only inputs.
- [x] F — extract `WorldSceneRenderer`, including both shared-alpha scopes,
PView/fallback world branches, particles, debug world draw, and completion.
- [ ] G — compose `RenderFrameOrchestrator`, cut `GameWindow.OnRender` to one
- [x] G — compose `RenderFrameOrchestrator`, cut `GameWindow.OnRender` to one
handoff, and delete obsolete frame bodies, fields, helpers, and callbacks.
- [ ] H — corrected-diff reviews, full Release suite, connected lifecycle and
soak gates, framebuffer comparison, documentation, memory, and metrics.
@ -231,12 +231,15 @@ contract requires separate approval and evidence.
### 4.2 Borrowed resources and shutdown
Slice 7 collaborators borrow the already-created GL/render owners. They do not
dispose them. The existing retryable shutdown transaction keeps its proven
dependency order: wait for submitted work; withdraw UI/render publications;
release textures and mesh owners; then dispose GL backing stores, with
`GpuFrameFlightController` last among render resources. Slice 8 may group
construction/disposal after the render cutover is stable.
The frame orchestrator and phase owners borrow the already-created GL/render
owners and do not dispose them. The developer-tools backend is itself the
canonical owner of its ImGui bootstrap and disposes that bootstrap when the
existing retryable shutdown transaction retires the backend; the frame
presenter only borrows it. Shutdown keeps its proven dependency order: wait for
submitted work; withdraw UI/render publications; release textures and mesh
owners; then dispose GL backing stores, with `GpuFrameFlightController` last
among render resources. Slice 8 may group construction/disposal after the
render cutover is stable.
`DisplayFramePacingController` is the focused shared owner for requested VSync,
live display preview, monitor/window callbacks, and the separate
@ -354,7 +357,8 @@ Completed 2026-07-22. Paperdoll clone/re-dress/pose/FBO work now belongs to
`PaperdollFramePresenter`; retained surfaces are narrow and optional, while
live identity and DAT pose application resolve through focused adapters.
`DevToolsFramePresenter` owns the ImGui frame, menus, panels, layout, and input
actions without taking shutdown ownership of the borrowed bootstrap.
actions while borrowing the bootstrap; `ImGuiDevToolsFrameBackend` explicitly
owns and disposes that bootstrap at shutdown.
`WorldRenderDiagnostics`, `DebugVmRenderFactsPublisher`, and
`RenderFrameDiagnosticsController` own the former render probes, debug facts,
title/resource cadence, and public snapshot. The production handoff now reports
@ -471,12 +475,29 @@ corrected-diff reviews are clean.
- compose concrete resource, world, private-presentation, and diagnostic owners;
- replace `OnRender` with one `RenderFrameOrchestrator.Render` handoff;
- remove obsolete fields/helpers/callbacks and prove the transitive render graph
has no substantial path back to `GameWindow`;
- preserve the existing shutdown resource list without transferring disposal;
- remove obsolete fields/helpers/callbacks; prove immediate frame owners retain
no direct `GameWindow`/anonymous-delegate back-reference, and document rather
than deny recursive paths through borrowed canonical UI/input owners;
- preserve the existing shutdown dependency order while making the
developer-tools backend's pre-existing bootstrap ownership explicit;
- measure line/field/method counts. Ownership decides completion; the expected
signal is roughly 5,0005,500 lines before Slice 8 composition cleanup.
Completed 2026-07-22. `GameWindow.OnRender` now creates one value-only
`RenderFrameInput` and hands the complete frame to `RenderFrameOrchestrator`.
Focused preparation, world-scene, private-presentation, and diagnostic owners
preserve the accepted resource → ImGui begin → weather → world → portal →
paperdoll → retained UI → ImGui submit → screenshot → diagnostics → GPU close
order. Recovery now closes an active ImGui frame through the owning Silk
controller and restores the exact text-render GL state after success or
failure. Screenshot dimensions travel in the frame input rather than through a
window callback, and immediate frame owners have no direct `GameWindow` or
anonymous-delegate back-reference. `GameWindow.cs` is 4,666 raw lines / 196
fields / 70 methods: 11,057 lines (70.3%) below the 15,723-line campaign
baseline. The Release build and complete suite pass (7,341 passed / 5 skipped),
and retail-conformance, architecture, and adversarial corrected-diff reviews
are clean.
### H — release and connected gates
After three clean corrected-diff reviews: