using AcDream.App.Rendering.Gpu.Gl; namespace AcDream.App.Tests.Rendering.Gpu.Gl; public sealed class GlGpuTimerPoolTests { [Fact] public void UnsupportedPoolReturnsNoOpScopesAndNeverResolves() { var pool = new GlGpuTimerPool(new FakeTimerQueryApi(), isSupported: false); using (pool.BeginScope("world")) { } Assert.False(pool.TryResolve("world", out _)); } [Fact] public void ScopeNamesGetIndependentDoubleBufferedQueries() { var api = new FakeTimerQueryApi(); var pool = new GlGpuTimerPool(api, isSupported: true); using (pool.BeginScope("world")) { } using (pool.BeginScope("ui")) { } Assert.Equal(4, api.CreatedQueryCount); } [Fact] public void NestingAScopeBeforeDisposingThePreviousOneThrows() { var pool = new GlGpuTimerPool(new FakeTimerQueryApi(), isSupported: true); pool.BeginScope("world"); Assert.Throws(() => pool.BeginScope("ui")); } [Fact] public void AResolvedResultIsPromotedTheNextTimeTheSameScopeBegins() { var api = new FakeTimerQueryApi(); var pool = new GlGpuTimerPool(api, isSupported: true); using (pool.BeginScope("world")) { } // No result available yet — the first slot hasn't been revisited. Assert.False(pool.TryResolve("world", out _)); api.MakeNextResultReady(milliseconds: 1.5); using (pool.BeginScope("world")) { } Assert.True(pool.TryResolve("world", out double milliseconds)); Assert.Equal(1.5, milliseconds); } [Fact] public void DisposeQueriesDeletesEveryCreatedQuery() { var api = new FakeTimerQueryApi(); var pool = new GlGpuTimerPool(api, isSupported: true); using (pool.BeginScope("world")) { } pool.DisposeQueries(); Assert.Equal(2, api.DeletedQueryCount); } private sealed class FakeTimerQueryApi : IGlTimerQueryApi { private uint _nextQuery = 1; private bool _nextResultReady; private double _nextResultMilliseconds; public int CreatedQueryCount { get; private set; } public int DeletedQueryCount { get; private set; } public uint CreateQuery() { CreatedQueryCount++; return _nextQuery++; } public void DeleteQuery(uint query) => DeletedQueryCount++; public void Begin(uint query) { } public void End() { } public void MakeNextResultReady(double milliseconds) { _nextResultReady = true; _nextResultMilliseconds = milliseconds; } public bool TryGetResult(uint query, out double milliseconds) { if (_nextResultReady) { milliseconds = _nextResultMilliseconds; _nextResultReady = false; return true; } milliseconds = 0; return false; } } }