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>
36 lines
1.2 KiB
C#
36 lines
1.2 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
namespace AcDream.App.Rendering.Wb;
|
|
|
|
/// <summary>
|
|
/// Thread-safe side-table mapping <c>(gfxObjId, surfaceIdx)</c> to
|
|
/// <see cref="AcSurfaceMetadata"/>. Populated when a GfxObj's mesh data
|
|
/// is extracted; queried at draw time.
|
|
///
|
|
/// <para>
|
|
/// Keyed by <c>(gfxObjId, surfaceIdx)</c> not by WB's runtime batch
|
|
/// identity because batch objects can be evicted and re-loaded by WB's
|
|
/// LRU; the (gfxObj, surface) pair is stable across cycles.
|
|
/// </para>
|
|
/// </summary>
|
|
public sealed class AcSurfaceMetadataTable
|
|
{
|
|
private readonly ConcurrentDictionary<(ulong gfxObjId, int surfaceIdx), AcSurfaceMetadata> _table = new();
|
|
|
|
public void Add(ulong gfxObjId, int surfaceIdx, AcSurfaceMetadata meta)
|
|
=> _table[(gfxObjId, surfaceIdx)] = meta;
|
|
|
|
public bool TryLookup(ulong gfxObjId, int surfaceIdx, out AcSurfaceMetadata meta)
|
|
=> _table.TryGetValue((gfxObjId, surfaceIdx), out meta!);
|
|
|
|
public void Remove(ulong gfxObjId)
|
|
{
|
|
foreach ((ulong Id, int SurfaceIndex) key in _table.Keys)
|
|
{
|
|
if (key.Id == gfxObjId)
|
|
_table.TryRemove(key, out _);
|
|
}
|
|
}
|
|
|
|
public void Clear() => _table.Clear();
|
|
}
|