fix(rendering): bound portal resource lifetime
Separate logical ownership, render publication, and GPU retirement across live entities, landblocks, particles, textures, mesh arenas, portal/UI teardown, and per-frame scratch storage. Add bounded DAT/texture caches, upload budgets, three-frame fence retirement, exact-incarnation appearance reconciliation, frame pacing, and extensive lifetime conformance coverage.\n\nThe seven-destination connected route now cuts peak working/private memory roughly in half, returns Caul to 125-153 FPS locally, and produces no WER or AMD reset.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
3971997689
commit
749e8ceeb1
225 changed files with 29107 additions and 3914 deletions
|
|
@ -50,6 +50,8 @@ public sealed class UiHost : System.IDisposable
|
|||
|
||||
private long _startTicks = System.Environment.TickCount64;
|
||||
private readonly List<System.Action> _inputUnsubscribers = new();
|
||||
private ResourceShutdownTransaction? _shutdown;
|
||||
private bool _disposeRequested;
|
||||
private bool _disposed;
|
||||
|
||||
public UiHost(GL gl, string shaderDir, BitmapFont? defaultFont = null)
|
||||
|
|
@ -81,7 +83,7 @@ public sealed class UiHost : System.IDisposable
|
|||
|
||||
public void WireMouse(IMouse mouse)
|
||||
{
|
||||
System.ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
System.ObjectDisposedException.ThrowIf(_disposeRequested || _disposed, this);
|
||||
System.ArgumentNullException.ThrowIfNull(mouse);
|
||||
|
||||
void OnMouseDown(IMouse sender, MouseButton button) =>
|
||||
|
|
@ -107,7 +109,7 @@ public sealed class UiHost : System.IDisposable
|
|||
|
||||
public void WireKeyboard(IKeyboard kb)
|
||||
{
|
||||
System.ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
System.ObjectDisposedException.ThrowIf(_disposeRequested || _disposed, this);
|
||||
System.ArgumentNullException.ThrowIfNull(kb);
|
||||
Keyboard = kb; // last wired keyboard wins (one-keyboard desktop)
|
||||
void OnKeyDown(IKeyboard sender, Key key, int scanCode) => Root.OnKeyDown((int)key);
|
||||
|
|
@ -162,13 +164,55 @@ public sealed class UiHost : System.IDisposable
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
for (int i = _inputUnsubscribers.Count - 1; i >= 0; i--)
|
||||
_inputUnsubscribers[i]();
|
||||
_inputUnsubscribers.Clear();
|
||||
Keyboard = null;
|
||||
WindowManager.Dispose();
|
||||
TextRenderer.Dispose();
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_disposeRequested = true;
|
||||
_shutdown ??= CreateShutdownTransaction(
|
||||
_inputUnsubscribers.AsEnumerable().Reverse().ToArray(),
|
||||
() =>
|
||||
{
|
||||
_inputUnsubscribers.Clear();
|
||||
Keyboard = null;
|
||||
},
|
||||
WindowManager.Dispose,
|
||||
TextRenderer.Dispose);
|
||||
_shutdown.CompleteOrThrow();
|
||||
_disposed = _shutdown.IsComplete;
|
||||
}
|
||||
|
||||
internal static ResourceShutdownTransaction CreateShutdownTransaction(
|
||||
IReadOnlyList<Action> inputUnsubscribers,
|
||||
Action releaseInputState,
|
||||
Action disposeWindowManager,
|
||||
Action disposeTextRenderer)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(inputUnsubscribers);
|
||||
ArgumentNullException.ThrowIfNull(releaseInputState);
|
||||
ArgumentNullException.ThrowIfNull(disposeWindowManager);
|
||||
ArgumentNullException.ThrowIfNull(disposeTextRenderer);
|
||||
|
||||
return new ResourceShutdownTransaction(
|
||||
new ResourceShutdownStage(
|
||||
"retained UI input subscriptions",
|
||||
inputUnsubscribers
|
||||
.Select((unsubscribe, index) => new ResourceShutdownOperation(
|
||||
$"input subscription {index}",
|
||||
unsubscribe ?? throw new ArgumentException(
|
||||
"Input unsubscriber entries cannot be null.",
|
||||
nameof(inputUnsubscribers))))
|
||||
.ToArray()),
|
||||
new ResourceShutdownStage("retained UI input state",
|
||||
[
|
||||
new("input state", releaseInputState),
|
||||
]),
|
||||
new ResourceShutdownStage("retained UI windows",
|
||||
[
|
||||
new("window manager", disposeWindowManager),
|
||||
]),
|
||||
new ResourceShutdownStage("retained UI renderer",
|
||||
[
|
||||
new("text renderer", disposeTextRenderer),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue