using AcDream.App.Rendering; namespace AcDream.App.Tests.Rendering; /// /// S4-c2 fix round 1 (M6, contract C4): /// is the queue-facing half of an EnvCell transparent shell's detail-off /// submission — one token per CELL, replayed through a caller-supplied /// delegate (production wiring: /// ) /// at whatever flush site the shared drains /// at. These tests exercise the REAL production class end-to-end against a /// real queue — only the render destination is faked (a delegate recording /// what it was asked to draw), so the GPU-backed EnvCellRenderer /// never needs to be constructed to pin the queue mechanics. /// public sealed class EnvCellAlphaDrawSourceTests { /// Mutation check: if SubmitOrDrawTransparentCellShell /// drew the cell immediately instead of appending it when detail is off /// (the M1/M3 bug class this chunk fixes elsewhere), the drawn list /// would already contain an entry BEFORE Flush runs — the /// Assert.Empty(drawn) line fails against that mutation. [Fact] public void PendingCellToken_IsDrainedAtTheFlushAndNeverBeforeIt() { var drawn = new List>(); var source = new RetailPViewPassExecutor.EnvCellAlphaDrawSource( cells => drawn.Add(cells.ToArray())); var queue = new RetailAlphaQueue(); queue.BeginFrame(); int token = source.AddPendingCellId(0x1234u); Assert.True(queue.TryAppend(RetailAlphaList.Alpha, source, token, false)); Assert.Empty(drawn); queue.Flush(RetailAlphaFlushSite.DrawBuilding, 0f); IReadOnlyList singleDraw = Assert.Single(drawn); Assert.Equal(new uint[] { 0x1234u }, singleDraw); queue.EndFrame(); } /// Two cell tokens from the SAME , /// with an unrelated source's entry appended between them, must still /// produce TWO separate single-cell draw calls around the interposed /// entry — 's "only adjacent /// same-source entries batch" invariant (the queue never groups across /// another entry, which is what keeps compositing order exact). Mutation /// check: an implementation that draws every prepared cell id in one /// call regardless of the requested (first, count) range would /// print both cell ids together on EACH of the two /// DrawPreparedAlphaBatch invocations instead of once each — the /// exact sequence assertion below fails against that mutation. [Fact] public void ParticleAppendedBetweenTwoCellTokens_KeepsItsPositionInTheCombinedDrain() { var log = new List(); var cellSource = new RetailPViewPassExecutor.EnvCellAlphaDrawSource( cells => log.Add($"cell:{string.Join(',', cells)}")); var particleSource = new RecordingSource("particle", log); var queue = new RetailAlphaQueue(); queue.BeginFrame(); int cell1Token = cellSource.AddPendingCellId(0x100u); Assert.True(queue.TryAppend(RetailAlphaList.Alpha, cellSource, cell1Token, false)); Assert.True(queue.TryAppend(RetailAlphaList.Alpha, particleSource, 7, false)); int cell2Token = cellSource.AddPendingCellId(0x200u); Assert.True(queue.TryAppend(RetailAlphaList.Alpha, cellSource, cell2Token, false)); queue.EndFrame(); Assert.Equal(new[] { "cell:256", "particle:7", "cell:512" }, log); } private sealed class RecordingSource(string name, List log) : IRetailAlphaDrawSource { private int[] _prepared = []; public void PrepareAlphaDraws(ReadOnlySpan tokens) => _prepared = tokens.ToArray(); public void DrawPreparedAlphaBatch(int firstPreparedDraw, int drawCount) { for (int i = 0; i < drawCount; i++) log.Add($"{name}:{_prepared[firstPreparedDraw + i]}"); } public void ResetAlphaSubmissions() { } } }