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

@ -20,7 +20,6 @@ internal sealed class FrameScreenshotController
private sealed record CaptureStatus(CaptureState State, string? Error = null);
private readonly Func<(int Width, int Height)> _getSize;
private readonly Func<int, int, byte[]> _readRgba;
private readonly string _directory;
private readonly Action<string> _log;
@ -30,21 +29,18 @@ internal sealed class FrameScreenshotController
public FrameScreenshotController(
GL gl,
Func<(int Width, int Height)> getSize,
string directory,
Action<string>? log = null)
: this(getSize, (width, height) => ReadDefaultFramebuffer(gl, width, height), directory, log)
: this((width, height) => ReadDefaultFramebuffer(gl, width, height), directory, log)
{
ArgumentNullException.ThrowIfNull(gl);
}
internal FrameScreenshotController(
Func<(int Width, int Height)> getSize,
Func<int, int, byte[]> readRgba,
string directory,
Action<string>? log = null)
{
_getSize = getSize ?? throw new ArgumentNullException(nameof(getSize));
_readRgba = readRgba ?? throw new ArgumentNullException(nameof(readRgba));
_directory = string.IsNullOrWhiteSpace(directory)
? throw new ArgumentException("A screenshot directory is required.", nameof(directory))
@ -76,7 +72,7 @@ internal sealed class FrameScreenshotController
&& status.State == CaptureState.Complete;
/// <summary>Captures at most one queued image on the current GL thread.</summary>
public bool CapturePending()
public bool CapturePending(int width, int height)
{
if (_pending.Count == 0)
return false;
@ -84,7 +80,6 @@ internal sealed class FrameScreenshotController
string name = _pending.Dequeue();
try
{
(int width, int height) = _getSize();
if (width <= 0 || height <= 0)
throw new InvalidOperationException($"invalid framebuffer size {width}x{height}");