fix #225: stabilize render pacing and frame CPU
Replace scheduler-quantized software sleeps with a reusable Windows high-resolution deadline timer, expose pacing in the frame profiler, and make shutdown wake every persistent mesh worker without losing the shared signal. Preserve retail alpha order while using a stable radix, skip duplicate deferred-alpha SSBO packing, pack light sets, cache static selection descriptors, and retire historical material groups at the whole-frame boundary. The fixed dense-Caul sample improved from roughly 9-12 ms CPU to 5.3-6.2 ms without reducing visual quality. Release build succeeds with zero warnings and all 6,300 tests pass with five intentional skips. Three independent retail, architecture, and adversarial reviews are clean; the post-review connected route remains pending because local ACE is offline. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
47d7086a74
commit
3718e341be
17 changed files with 1103 additions and 225 deletions
|
|
@ -10871,7 +10871,9 @@ public sealed class GameWindow : IDisposable
|
|||
$"acdream | {fps:F0} fps | {avgFrameTime:F1} ms | "
|
||||
+ $"lb {visibleLandblocks}/{totalLandblocks} | ent {entityCount}/anim {animatedCount} | "
|
||||
+ $"PY{titleCal.Year} {titleCal.Month} {titleCal.Day} {titleCal.Hour} (df={df:F4})";
|
||||
if (_options.UiProbeEnabled)
|
||||
// Script automation must remain performance-neutral. Only the
|
||||
// explicit dump switch requests this allocation-heavy snapshot.
|
||||
if (_options.UiProbeDump)
|
||||
{
|
||||
(int particleSets, long particleBytes) =
|
||||
_particleRenderer?.DynamicBufferDiagnostics ?? default;
|
||||
|
|
@ -12893,7 +12895,11 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
|
||||
private void OnFrameRendered(double _)
|
||||
=> _framePacing.CompleteFrame();
|
||||
{
|
||||
using var pacingStage = _frameProfiler.BeginStage(
|
||||
AcDream.App.Diagnostics.FrameStage.Pacing);
|
||||
_framePacing.CompleteFrame();
|
||||
}
|
||||
|
||||
private void OnWindowMoved(Silk.NET.Maths.Vector2D<int> _)
|
||||
=> RefreshActiveMonitorFramePacing();
|
||||
|
|
@ -15022,6 +15028,9 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
|
||||
private void OnClosing()
|
||||
=> CompleteShutdown();
|
||||
|
||||
private void CompleteShutdown()
|
||||
{
|
||||
_shutdown ??= CreateShutdownTransaction();
|
||||
try
|
||||
|
|
@ -15036,7 +15045,6 @@ public sealed class GameWindow : IDisposable
|
|||
// context/process teardown is the final safety net.
|
||||
Console.Error.WriteLine($"[shutdown] {error}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ResourceShutdownTransaction CreateShutdownTransaction() => new(
|
||||
|
|
@ -15160,6 +15168,7 @@ public sealed class GameWindow : IDisposable
|
|||
new("text renderer", () => _textRenderer?.Dispose()),
|
||||
new("debug font", () => _debugFont?.Dispose()),
|
||||
new("frame profiler", _frameProfiler.Dispose),
|
||||
new("frame pacing", _framePacing.Dispose),
|
||||
]),
|
||||
new ResourceShutdownStage("frame flight owner",
|
||||
[
|
||||
|
|
@ -15202,7 +15211,17 @@ public sealed class GameWindow : IDisposable
|
|||
EndMouseLookAndRestoreCursor();
|
||||
}
|
||||
|
||||
public void Dispose() => _window?.Dispose();
|
||||
public void Dispose()
|
||||
{
|
||||
// Closing is the normal path and runs while the render context is
|
||||
// current. This direct call also covers a constructed-but-never-run
|
||||
// window and exceptions during Window.Create/Run, so owned kernel
|
||||
// handles (including the frame timer) never depend on a native window
|
||||
// event for disposal.
|
||||
CompleteShutdown();
|
||||
_window?.Dispose();
|
||||
_window = null;
|
||||
}
|
||||
|
||||
// ── Phase I.6 — TurbineChat outbound helpers ──────────────────
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue